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-async-storage')
|
||||||
implementation project(':react-native-background-timer')
|
implementation project(':react-native-background-timer')
|
||||||
implementation project(':react-native-calendar-events')
|
implementation project(':react-native-calendar-events')
|
||||||
|
implementation project(':react-native-community_clipboard')
|
||||||
implementation project(':react-native-community_netinfo')
|
implementation project(':react-native-community_netinfo')
|
||||||
implementation project(':react-native-default-preference')
|
implementation project(':react-native-default-preference')
|
||||||
implementation project(':react-native-gesture-handler')
|
implementation project(':react-native-gesture-handler')
|
||||||
|
|
|
@ -180,6 +180,7 @@ class ReactInstanceManagerHolder {
|
||||||
new com.calendarevents.CalendarEventsPackage(),
|
new com.calendarevents.CalendarEventsPackage(),
|
||||||
new com.corbt.keepawake.KCKeepAwakePackage(),
|
new com.corbt.keepawake.KCKeepAwakePackage(),
|
||||||
new com.facebook.react.shell.MainReactPackage(),
|
new com.facebook.react.shell.MainReactPackage(),
|
||||||
|
new com.reactnativecommunity.clipboard.ClipboardPackage(),
|
||||||
new com.reactnativecommunity.netinfo.NetInfoPackage(),
|
new com.reactnativecommunity.netinfo.NetInfoPackage(),
|
||||||
new com.oblador.performance.PerformancePackage(),
|
new com.oblador.performance.PerformancePackage(),
|
||||||
new com.reactnativecommunity.slider.ReactSliderPackage(),
|
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')
|
project(':react-native-background-timer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-background-timer/android')
|
||||||
include ':react-native-calendar-events'
|
include ':react-native-calendar-events'
|
||||||
project(':react-native-calendar-events').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-calendar-events/android')
|
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'
|
include ':react-native-community_netinfo'
|
||||||
project(':react-native-community_netinfo').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/netinfo/android')
|
project(':react-native-community_netinfo').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/netinfo/android')
|
||||||
include ':react-native-default-preference'
|
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-keep-awake', :path => '../node_modules/react-native-keep-awake'
|
||||||
pod 'react-native-netinfo', :path => '../node_modules/@react-native-community/netinfo'
|
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-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-slider', :path => '../node_modules/@react-native-community/slider'
|
||||||
pod 'react-native-splash-screen', :path => '../node_modules/react-native-splash-screen'
|
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-video', :path => '../node_modules/react-native-video/react-native-video.podspec'
|
||||||
pod 'react-native-webview', :path => '../node_modules/react-native-webview'
|
pod 'react-native-webview', :path => '../node_modules/react-native-webview'
|
||||||
pod 'react-native-webrtc', :path => '../node_modules/react-native-webrtc'
|
pod 'react-native-webrtc', :path => '../node_modules/react-native-webrtc'
|
||||||
pod 'RNCAsyncStorage', :path => '../node_modules/@react-native-async-storage/async-storage'
|
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 '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 '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 'RNSound', :path => '../node_modules/react-native-sound'
|
||||||
pod 'RNSVG', :path => '../node_modules/react-native-svg'
|
pod 'RNSVG', :path => '../node_modules/react-native-svg'
|
||||||
pod 'RNWatch', :path => '../node_modules/react-native-watch-connectivity'
|
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
|
# Native pod dependencies
|
||||||
#
|
#
|
||||||
|
|
|
@ -363,6 +363,8 @@ PODS:
|
||||||
- ReactCommon/turbomodule/core (= 0.61.5-jitsi.2)
|
- ReactCommon/turbomodule/core (= 0.61.5-jitsi.2)
|
||||||
- RNCAsyncStorage (1.15.5):
|
- RNCAsyncStorage (1.15.5):
|
||||||
- React-Core
|
- React-Core
|
||||||
|
- RNCClipboard (1.5.1):
|
||||||
|
- React-Core
|
||||||
- RNCMaskedView (0.2.6):
|
- RNCMaskedView (0.2.6):
|
||||||
- React-Core
|
- React-Core
|
||||||
- RNDefaultPreference (1.4.2):
|
- RNDefaultPreference (1.4.2):
|
||||||
|
@ -435,6 +437,7 @@ DEPENDENCIES:
|
||||||
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
|
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
|
||||||
- ReactCommon/turbomodule (from `../node_modules/react-native/ReactCommon`)
|
- ReactCommon/turbomodule (from `../node_modules/react-native/ReactCommon`)
|
||||||
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
|
- "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`)"
|
- "RNCMaskedView (from `../node_modules/@react-native-masked-view/masked-view`)"
|
||||||
- RNDefaultPreference (from `../node_modules/react-native-default-preference`)
|
- RNDefaultPreference (from `../node_modules/react-native-default-preference`)
|
||||||
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
|
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
|
||||||
|
@ -547,6 +550,8 @@ EXTERNAL SOURCES:
|
||||||
:path: "../node_modules/react-native/ReactCommon"
|
:path: "../node_modules/react-native/ReactCommon"
|
||||||
RNCAsyncStorage:
|
RNCAsyncStorage:
|
||||||
:path: "../node_modules/@react-native-async-storage/async-storage"
|
:path: "../node_modules/@react-native-async-storage/async-storage"
|
||||||
|
RNCClipboard:
|
||||||
|
:path: "../node_modules/@react-native-community/clipboard"
|
||||||
RNCMaskedView:
|
RNCMaskedView:
|
||||||
:path: "../node_modules/@react-native-masked-view/masked-view"
|
:path: "../node_modules/@react-native-masked-view/masked-view"
|
||||||
RNDefaultPreference:
|
RNDefaultPreference:
|
||||||
|
@ -629,6 +634,7 @@ SPEC CHECKSUMS:
|
||||||
React-RCTVibration: c1041024893fdfdb8371e7c720c437751b711676
|
React-RCTVibration: c1041024893fdfdb8371e7c720c437751b711676
|
||||||
ReactCommon: 18014e1d98dbeb9141e935cfe35fc93bd511ffb6
|
ReactCommon: 18014e1d98dbeb9141e935cfe35fc93bd511ffb6
|
||||||
RNCAsyncStorage: 56a3355a10b5d660c48c6e37325ac85ebfd09885
|
RNCAsyncStorage: 56a3355a10b5d660c48c6e37325ac85ebfd09885
|
||||||
|
RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495
|
||||||
RNCMaskedView: c298b644a10c0c142055b3ae24d83879ecb13ccd
|
RNCMaskedView: c298b644a10c0c142055b3ae24d83879ecb13ccd
|
||||||
RNDefaultPreference: 1f8133ec0bc0f9453cdada578564ba1ef551fb44
|
RNDefaultPreference: 1f8133ec0bc0f9453cdada578564ba1ef551fb44
|
||||||
RNDeviceInfo: 87d2d175c760f6bcf58acd036f887e8b2392802c
|
RNDeviceInfo: 87d2d175c760f6bcf58acd036f887e8b2392802c
|
||||||
|
@ -641,6 +647,6 @@ SPEC CHECKSUMS:
|
||||||
RNWatch: a5320c959c75e72845c07985f3e935e58998f1d3
|
RNWatch: a5320c959c75e72845c07985f3e935e58998f1d3
|
||||||
Yoga: 96b469c5e81ff51b917b92e8c3390642d4ded30c
|
Yoga: 96b469c5e81ff51b917b92e8c3390642d4ded30c
|
||||||
|
|
||||||
PODFILE CHECKSUM: 836d4804218c0608e1326471ec83fe31cfa9c86d
|
PODFILE CHECKSUM: 0cfc1f35e2872ceb0a86252e14e226bd489a2602
|
||||||
|
|
||||||
COCOAPODS: 1.11.2
|
COCOAPODS: 1.11.2
|
||||||
|
|
|
@ -824,8 +824,8 @@
|
||||||
"security": {
|
"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.",
|
"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.",
|
"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.",
|
"header": "Security Options",
|
||||||
"securityOptions": "Security options"
|
"insecureRoomNameWarning": "The room name is unsafe. Unwanted participants may join your conference. Consider securing your meeting using the security button."
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"calendar": {
|
"calendar": {
|
||||||
|
@ -893,20 +893,20 @@
|
||||||
},
|
},
|
||||||
"speaker": "Speaker",
|
"speaker": "Speaker",
|
||||||
"speakerStats": {
|
"speakerStats": {
|
||||||
"search": "Search",
|
"angry": "Angry",
|
||||||
|
"disgusted": "Disgusted",
|
||||||
|
"fearful": "Fearful",
|
||||||
|
"happy": "Happy",
|
||||||
"hours": "{{count}}h",
|
"hours": "{{count}}h",
|
||||||
"minutes": "{{count}}m",
|
"minutes": "{{count}}m",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"seconds": "{{count}}s",
|
|
||||||
"speakerStats": "Speaker Stats",
|
|
||||||
"speakerTime": "Speaker Time",
|
|
||||||
"happy": "Happy",
|
|
||||||
"neutral": "Neutral",
|
"neutral": "Neutral",
|
||||||
"sad": "Sad",
|
"sad": "Sad",
|
||||||
"surprised": "Surprised",
|
"search": "Search",
|
||||||
"angry": "Angry",
|
"seconds": "{{count}}s",
|
||||||
"fearful": "Fearful",
|
"speakerTime": "Speaker Time",
|
||||||
"disgusted": "Disgusted"
|
"speakerStats": "Speaker Stats",
|
||||||
|
"surprised": "Surprised"
|
||||||
},
|
},
|
||||||
"startupoverlay": {
|
"startupoverlay": {
|
||||||
"policyText": " ",
|
"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",
|
"@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",
|
"@microsoft/microsoft-graph-client": "1.1.0",
|
||||||
"@react-native-async-storage/async-storage": "1.15.5",
|
"@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/google-signin": "3.0.1",
|
||||||
"@react-native-community/netinfo": "4.1.5",
|
"@react-native-community/netinfo": "4.1.5",
|
||||||
"@react-native-community/slider": "3.0.3",
|
"@react-native-community/slider": "3.0.3",
|
||||||
|
@ -4097,6 +4098,15 @@
|
||||||
"node": ">=8"
|
"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": {
|
"node_modules/@react-native-community/google-signin": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/google-signin/-/google-signin-3.0.1.tgz",
|
"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",
|
"resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-3.0.0.tgz",
|
||||||
"integrity": "sha512-ng6Tm537E/M42GjE4TRUxQyL8sRfClcL7bQWblOCoxPZzJ2J3bdALsjeG3vDnVCIfI/R0AeFalN9KjMt0+Z/Zg=="
|
"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": {
|
"@react-native-community/google-signin": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/google-signin/-/google-signin-3.0.1.tgz",
|
"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",
|
"@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",
|
"@microsoft/microsoft-graph-client": "1.1.0",
|
||||||
"@react-native-async-storage/async-storage": "1.15.5",
|
"@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/google-signin": "3.0.1",
|
||||||
"@react-native-community/netinfo": "4.1.5",
|
"@react-native-community/netinfo": "4.1.5",
|
||||||
"@react-native-community/slider": "3.0.3",
|
"@react-native-community/slider": "3.0.3",
|
||||||
|
|
|
@ -19,6 +19,7 @@ export const colors = {
|
||||||
primary09: '#CCDDF9',
|
primary09: '#CCDDF9',
|
||||||
primary10: '#17A0DB',
|
primary10: '#17A0DB',
|
||||||
primary11: '#1081B2',
|
primary11: '#1081B2',
|
||||||
|
primary12: '#B8C7E0',
|
||||||
|
|
||||||
surface00: '#111111',
|
surface00: '#111111',
|
||||||
surface01: '#040404',
|
surface01: '#040404',
|
||||||
|
@ -158,6 +159,9 @@ export const colorMap = {
|
||||||
// Text for drawer menu displayed name
|
// Text for drawer menu displayed name
|
||||||
text05: 'surface06',
|
text05: 'surface06',
|
||||||
|
|
||||||
|
// Text for saved input values
|
||||||
|
text06: 'surface03',
|
||||||
|
|
||||||
// error messages
|
// error messages
|
||||||
textError: 'error06',
|
textError: 'error06',
|
||||||
|
|
||||||
|
@ -226,6 +230,8 @@ export const colorMap = {
|
||||||
// Line separators
|
// Line separators
|
||||||
border03: 'surface04',
|
border03: 'surface04',
|
||||||
|
|
||||||
|
border04: 'primary12',
|
||||||
|
|
||||||
// Color for error border & message
|
// Color for error border & message
|
||||||
borderError: 'error06',
|
borderError: 'error06',
|
||||||
|
|
||||||
|
|
|
@ -17,12 +17,12 @@ import {
|
||||||
setVideoMuted
|
setVideoMuted
|
||||||
} from '../base/media';
|
} from '../base/media';
|
||||||
import { getRemoteParticipants } from '../base/participants';
|
import { getRemoteParticipants } from '../base/participants';
|
||||||
import { createDesiredLocalTracks } from '../base/tracks/actions';
|
|
||||||
import {
|
import {
|
||||||
getLocalTracks,
|
getLocalTracks,
|
||||||
isLocalCameraTrackMuted,
|
isLocalCameraTrackMuted,
|
||||||
isLocalTrackMuted
|
isLocalTrackMuted
|
||||||
} from '../base/tracks';
|
} from '../base/tracks';
|
||||||
|
import { createDesiredLocalTracks } from '../base/tracks/actions';
|
||||||
import {
|
import {
|
||||||
NOTIFICATION_TIMEOUT_TYPE,
|
NOTIFICATION_TIMEOUT_TYPE,
|
||||||
clearNotifications,
|
clearNotifications,
|
||||||
|
|
|
@ -13,6 +13,8 @@ import AddPeopleDialog
|
||||||
from '../../../invite/components/add-people-dialog/native/AddPeopleDialog';
|
from '../../../invite/components/add-people-dialog/native/AddPeopleDialog';
|
||||||
import LobbyScreen from '../../../lobby/components/native/LobbyScreen';
|
import LobbyScreen from '../../../lobby/components/native/LobbyScreen';
|
||||||
import { ParticipantsPane } from '../../../participants-pane/components/native';
|
import { ParticipantsPane } from '../../../participants-pane/components/native';
|
||||||
|
import SecurityDialog
|
||||||
|
from '../../../security/components/security-dialog/native/SecurityDialog';
|
||||||
import SpeakerStats
|
import SpeakerStats
|
||||||
from '../../../speaker-stats/components/native/SpeakerStats';
|
from '../../../speaker-stats/components/native/SpeakerStats';
|
||||||
import { getDisablePolls } from '../../functions';
|
import { getDisablePolls } from '../../functions';
|
||||||
|
@ -28,6 +30,7 @@ import {
|
||||||
lobbyScreenOptions,
|
lobbyScreenOptions,
|
||||||
navigationContainerTheme,
|
navigationContainerTheme,
|
||||||
participantsScreenOptions,
|
participantsScreenOptions,
|
||||||
|
securityScreenOptions,
|
||||||
sharedDocumentScreenOptions,
|
sharedDocumentScreenOptions,
|
||||||
speakerStatsScreenOptions
|
speakerStatsScreenOptions
|
||||||
} from './ConferenceNavigatorScreenOptions';
|
} from './ConferenceNavigatorScreenOptions';
|
||||||
|
@ -80,11 +83,19 @@ const ConferenceNavigationContainer = () => {
|
||||||
...participantsScreenOptions,
|
...participantsScreenOptions,
|
||||||
title: t('participantsPane.header')
|
title: t('participantsPane.header')
|
||||||
}} />
|
}} />
|
||||||
|
<ConferenceStack.Screen
|
||||||
|
component = { SecurityDialog }
|
||||||
|
name = { screen.conference.security }
|
||||||
|
options = {{
|
||||||
|
...securityScreenOptions,
|
||||||
|
title: t('security.header')
|
||||||
|
}} />
|
||||||
<ConferenceStack.Screen
|
<ConferenceStack.Screen
|
||||||
component = { SpeakerStats }
|
component = { SpeakerStats }
|
||||||
name = { screen.conference.speakerStats }
|
name = { screen.conference.speakerStats }
|
||||||
options = {{
|
options = {{
|
||||||
...speakerStatsScreenOptions
|
...speakerStatsScreenOptions,
|
||||||
|
title: t('speakerStats.speakerStats')
|
||||||
}} />
|
}} />
|
||||||
<ConferenceStack.Screen
|
<ConferenceStack.Screen
|
||||||
component = { LobbyScreen }
|
component = { LobbyScreen }
|
||||||
|
|
|
@ -222,6 +222,13 @@ export const speakerStatsScreenOptions = {
|
||||||
...presentationScreenOptions
|
...presentationScreenOptions
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Screen options for security options modal.
|
||||||
|
*/
|
||||||
|
export const securityScreenOptions = {
|
||||||
|
...presentationScreenOptions
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Screen options for shared document.
|
* Screen options for shared document.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -21,6 +21,7 @@ export const screen = {
|
||||||
polls: 'Polls'
|
polls: 'Polls'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
security: 'Security Options',
|
||||||
speakerStats: 'Speaker Stats',
|
speakerStats: 'Speaker Stats',
|
||||||
participants: 'Participants',
|
participants: 'Participants',
|
||||||
invite: 'Invite',
|
invite: 'Invite',
|
||||||
|
|
|
@ -147,8 +147,8 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
||||||
<TouchableRipple
|
<TouchableRipple
|
||||||
disabled = { this._isAddDisabled() }
|
disabled = { this._isAddDisabled() }
|
||||||
rippleColor = { palette.screen01Header } >
|
rippleColor = { palette.screen01Header } >
|
||||||
<Text
|
<Text style = { styles.headerSendInvite }>
|
||||||
style = { styles.headerSendInvite }>{ t('inviteDialog.send') }
|
{ t('inviteDialog.send') }
|
||||||
</Text>
|
</Text>
|
||||||
</TouchableRipple>
|
</TouchableRipple>
|
||||||
)
|
)
|
||||||
|
@ -171,9 +171,8 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
||||||
disabled = { this._isAddDisabled() }
|
disabled = { this._isAddDisabled() }
|
||||||
onPress = { this._onInvite }
|
onPress = { this._onInvite }
|
||||||
rippleColor = { palette.screen01Header } >
|
rippleColor = { palette.screen01Header } >
|
||||||
<Text
|
<Text style = { styles.headerSendInvite }>
|
||||||
/* eslint-disable-next-line react-native/no-inline-styles */
|
{ t('inviteDialog.send') }
|
||||||
style = { styles.headerSendInvite }>{ t('inviteDialog.send') }
|
|
||||||
</Text>
|
</Text>
|
||||||
</TouchableRipple>
|
</TouchableRipple>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// @flow
|
// @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_THUMB_COLOR = BaseTheme.palette.action04;
|
||||||
export const ENABLED_TRACK_COLOR = ColorPalette.blue;
|
export const ENABLED_TRACK_COLOR = BaseTheme.palette.screen01Header;
|
||||||
export const DISABLED_THUMB_COLOR = ColorPalette.darkGrey;
|
export const DISABLED_THUMB_COLOR = BaseTheme.palette.icon04;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
button: {
|
button: {
|
||||||
|
@ -61,7 +61,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
fieldError: {
|
fieldError: {
|
||||||
color: ColorPalette.warning,
|
color: BaseTheme.palette.warning07,
|
||||||
fontSize: 10
|
fontSize: 10
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ export default {
|
||||||
|
|
||||||
lobbySwitchContainer: {
|
lobbySwitchContainer: {
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
marginTop: 16
|
marginTop: BaseTheme.spacing[2]
|
||||||
},
|
},
|
||||||
|
|
||||||
lobbySwitchIcon: {
|
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,
|
MEETING_PASSWORD_ENABLED,
|
||||||
SECURITY_OPTIONS_ENABLED
|
SECURITY_OPTIONS_ENABLED
|
||||||
} from '../../../base/flags';
|
} from '../../../base/flags';
|
||||||
import { translate } from '../../../base/i18n';
|
|
||||||
import { IconSecurityOff, IconSecurityOn } from '../../../base/icons';
|
import { IconSecurityOff, IconSecurityOn } from '../../../base/icons';
|
||||||
import { isLocalParticipantModerator } from '../../../base/participants';
|
import { isLocalParticipantModerator } from '../../../base/participants';
|
||||||
import { connect } from '../../../base/redux';
|
|
||||||
import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox/components';
|
import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox/components';
|
||||||
import { toggleSecurityDialog } from '../../actions';
|
|
||||||
|
|
||||||
|
export type Props = AbstractButtonProps & {
|
||||||
type Props = AbstractButtonProps & {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the shared document is being edited or not.
|
* 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';
|
accessibilityLabel = 'toolbar.accessibilityLabel.security';
|
||||||
icon = IconSecurityOff;
|
icon = IconSecurityOff;
|
||||||
label = 'toolbar.security';
|
label = 'toolbar.security';
|
||||||
|
@ -42,13 +39,24 @@ class SecurityDialogButton extends AbstractButton<Props, *> {
|
||||||
tooltip = 'toolbar.security';
|
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
|
* @private
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_handleClick() {
|
_handleClick() {
|
||||||
const { _locked, dispatch, handleClick } = this.props;
|
const { _locked, handleClick } = this.props;
|
||||||
|
|
||||||
if (handleClick) {
|
if (handleClick) {
|
||||||
handleClick();
|
handleClick();
|
||||||
|
@ -57,7 +65,7 @@ class SecurityDialogButton extends AbstractButton<Props, *> {
|
||||||
}
|
}
|
||||||
|
|
||||||
sendAnalytics(createToolbarEvent('toggle.security', { enable: !_locked }));
|
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.
|
* @param {Object} state - The redux store/state.
|
||||||
* @returns {Props}
|
* @returns {Props}
|
||||||
*/
|
*/
|
||||||
function mapStateToProps(state: Object) {
|
export function _mapStateToProps(state: Object) {
|
||||||
const { conference } = state['features/base/conference'];
|
const { conference } = state['features/base/conference'];
|
||||||
const { hideLobbyButton } = state['features/base/config'];
|
const { hideLobbyButton } = state['features/base/config'];
|
||||||
const { locked } = state['features/base/conference'];
|
const { locked } = state['features/base/conference'];
|
||||||
|
@ -93,5 +101,3 @@ function mapStateToProps(state: Object) {
|
||||||
visible: enabledFlag || (enabledLobbyModeFlag || enabledMeetingPassFlag)
|
visible: enabledFlag || (enabledLobbyModeFlag || enabledMeetingPassFlag)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default translate(connect(mapStateToProps)(SecurityDialogButton));
|
|
|
@ -1,35 +1,39 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
|
import Clipboard from '@react-native-community/clipboard';
|
||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import {
|
import {
|
||||||
KeyboardAvoidingView,
|
|
||||||
Platform,
|
|
||||||
Text,
|
Text,
|
||||||
TextInput,
|
TextInput,
|
||||||
View
|
View
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { TouchableRipple } from 'react-native-paper';
|
||||||
import type { Dispatch } from 'redux';
|
import type { Dispatch } from 'redux';
|
||||||
|
|
||||||
import { ColorSchemeRegistry } from '../../../../base/color-scheme';
|
import { ColorSchemeRegistry } from '../../../../base/color-scheme';
|
||||||
import {
|
import { FIELD_UNDERLINE } from '../../../../base/dialog';
|
||||||
FIELD_UNDERLINE,
|
|
||||||
CustomSubmitDialog
|
|
||||||
} from '../../../../base/dialog';
|
|
||||||
import { getFeatureFlag, MEETING_PASSWORD_ENABLED } from '../../../../base/flags';
|
import { getFeatureFlag, MEETING_PASSWORD_ENABLED } from '../../../../base/flags';
|
||||||
import { translate } from '../../../../base/i18n';
|
import { translate } from '../../../../base/i18n';
|
||||||
|
import { IconClose } from '../../../../base/icons';
|
||||||
|
import JitsiScreen from '../../../../base/modal/components/JitsiScreen';
|
||||||
import { isLocalParticipantModerator } from '../../../../base/participants';
|
import { isLocalParticipantModerator } from '../../../../base/participants';
|
||||||
|
import { connect } from '../../../../base/redux';
|
||||||
import { StyleType } from '../../../../base/styles';
|
import { StyleType } from '../../../../base/styles';
|
||||||
|
import BaseTheme from '../../../../base/ui/components/BaseTheme';
|
||||||
import { isInBreakoutRoom } from '../../../../breakout-rooms/functions';
|
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 { toggleLobbyMode } from '../../../../lobby/actions.any';
|
||||||
import LobbyModeSwitch
|
import LobbyModeSwitch
|
||||||
from '../../../../lobby/components/native/LobbyModeSwitch';
|
from '../../../../lobby/components/native/LobbyModeSwitch';
|
||||||
import { LOCKED_LOCALLY } from '../../../../room-lock';
|
import { LOCKED_LOCALLY, LOCKED_REMOTELY } from '../../../../room-lock';
|
||||||
import {
|
import {
|
||||||
endRoomLockRequest,
|
endRoomLockRequest,
|
||||||
unlockRoom
|
unlockRoom
|
||||||
} from '../../../../room-lock/actions';
|
} 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
|
* The style of the {@link TextInput} rendered by {@code SecurityDialog}. As it
|
||||||
|
@ -93,20 +97,20 @@ type Props = {
|
||||||
_passwordNumberOfDigits: number,
|
_passwordNumberOfDigits: number,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the room lock switch is available or not.
|
* Whether setting a room password is available or not.
|
||||||
*/
|
*/
|
||||||
_roomLockSwitchVisible: boolean,
|
_roomPasswordControls: boolean,
|
||||||
|
|
||||||
/**
|
|
||||||
* The color-schemed stylesheet of the security dialog feature.
|
|
||||||
*/
|
|
||||||
_securityDialogStyles: StyleType,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redux store dispatch function.
|
* Redux store dispatch function.
|
||||||
*/
|
*/
|
||||||
dispatch: Dispatch<any>,
|
dispatch: Dispatch<any>,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default prop for navigation between screen components(React Navigation).
|
||||||
|
*/
|
||||||
|
navigation: Object,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked to obtain translated strings.
|
* Invoked to obtain translated strings.
|
||||||
*/
|
*/
|
||||||
|
@ -150,9 +154,31 @@ class SecurityDialog extends PureComponent<Props, State> {
|
||||||
};
|
};
|
||||||
|
|
||||||
this._onChangeText = this._onChangeText.bind(this);
|
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._onSubmit = this._onSubmit.bind(this);
|
||||||
this._onToggleLobbyMode = this._onToggleLobbyMode.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() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<CustomSubmitDialog
|
<JitsiScreen style = { styles.securityDialogContainer }>
|
||||||
onSubmit = { this._onSubmit }>
|
|
||||||
<KeyboardAvoidingView
|
|
||||||
behavior =
|
|
||||||
{
|
|
||||||
Platform.OS === 'ios'
|
|
||||||
? 'padding' : 'height'
|
|
||||||
}
|
|
||||||
enabled = { true }>
|
|
||||||
{ this._renderLobbyMode() }
|
{ this._renderLobbyMode() }
|
||||||
{ this._renderRoomLock() }
|
{ this._renderSetRoomPassword() }
|
||||||
</KeyboardAvoidingView>
|
</JitsiScreen>
|
||||||
</CustomSubmitDialog>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +205,6 @@ class SecurityDialog extends PureComponent<Props, State> {
|
||||||
const {
|
const {
|
||||||
_lobbyEnabled,
|
_lobbyEnabled,
|
||||||
_lobbyModeSwitchVisible,
|
_lobbyModeSwitchVisible,
|
||||||
_securityDialogStyles,
|
|
||||||
t
|
t
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
@ -197,55 +213,151 @@ class SecurityDialog extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View>
|
<View style = { styles.lobbyModeContainer }>
|
||||||
<Text style = { _securityDialogStyles.title } >
|
<View style = { styles.lobbyModeContent } >
|
||||||
{ t('lobby.dialogTitle') }
|
<Text>
|
||||||
</Text>
|
|
||||||
<Text style = { _securityDialogStyles.text } >
|
|
||||||
{ t('lobby.enableDialogText') }
|
{ t('lobby.enableDialogText') }
|
||||||
</Text>
|
</Text>
|
||||||
|
<View style = { styles.lobbyModeSection }>
|
||||||
|
<Text style = { styles.lobbyModeLabel } >
|
||||||
|
{ t('lobby.toggleLabel') }
|
||||||
|
</Text>
|
||||||
<LobbyModeSwitch
|
<LobbyModeSwitch
|
||||||
lobbyEnabled = { _lobbyEnabled }
|
lobbyEnabled = { _lobbyEnabled }
|
||||||
onToggleLobbyMode = { this._onToggleLobbyMode } />
|
onToggleLobbyMode = { this._onToggleLobbyMode } />
|
||||||
</View>
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders room lock.
|
* Renders setting the password.
|
||||||
*
|
*
|
||||||
* @returns {ReactElement}
|
* @returns {ReactElement}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_renderRoomLock() {
|
_renderSetRoomPassword() {
|
||||||
const {
|
const {
|
||||||
_isModerator,
|
_isModerator,
|
||||||
_locked,
|
_locked,
|
||||||
_lockedConference,
|
_lockedConference,
|
||||||
_roomLockSwitchVisible,
|
_password,
|
||||||
_securityDialogStyles,
|
_roomPasswordControls,
|
||||||
t
|
t
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { showElement } = this.state;
|
const { showElement } = this.state;
|
||||||
|
let setPasswordControls;
|
||||||
|
|
||||||
if (!_roomLockSwitchVisible) {
|
if (!_roomPasswordControls) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
if (_locked && showElement) {
|
||||||
<View>
|
setPasswordControls = (
|
||||||
<Text style = { _securityDialogStyles.title } >
|
<>
|
||||||
{ t('dialog.lockRoom') }
|
<TouchableRipple
|
||||||
|
onPress = { this._onCancel }
|
||||||
|
rippleColor = { BaseTheme.palette.field02 } >
|
||||||
|
<Text style = { styles.passwordSetupButton }>
|
||||||
|
{ t('dialog.Remove') }
|
||||||
</Text>
|
</Text>
|
||||||
<Text style = { _securityDialogStyles.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
|
||||||
|
style = { styles.passwordContainer } >
|
||||||
|
<Text>
|
||||||
{ t('security.about') }
|
{ t('security.about') }
|
||||||
</Text>
|
</Text>
|
||||||
<RoomLockSwitch
|
<View
|
||||||
disabled = { !_isModerator }
|
style = {
|
||||||
locked = { _locked }
|
_locked !== LOCKED_REMOTELY
|
||||||
onToggleRoomLock = { this._onToggleRoomLock }
|
&& styles.passwordContainerControls
|
||||||
toggleRoomLock = { showElement || _lockedConference } />
|
}>
|
||||||
{ this._renderRoomLockMessage() }
|
<View>
|
||||||
|
{ this._setRoomPasswordMessage() }
|
||||||
|
</View>
|
||||||
|
{ setPasswordControls }
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -256,14 +368,13 @@ class SecurityDialog extends PureComponent<Props, State> {
|
||||||
* @returns {ReactElement}
|
* @returns {ReactElement}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_renderRoomLockMessage() {
|
_setRoomPasswordMessage() {
|
||||||
let textInputProps = _TEXT_INPUT_PROPS;
|
let textInputProps = _TEXT_INPUT_PROPS;
|
||||||
const {
|
const {
|
||||||
_isModerator,
|
_isModerator,
|
||||||
_locked,
|
_locked,
|
||||||
_password,
|
_password,
|
||||||
_passwordNumberOfDigits,
|
_passwordNumberOfDigits,
|
||||||
_securityDialogStyles,
|
|
||||||
t
|
t
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { passwordInputValue, showElement } = this.state;
|
const { passwordInputValue, showElement } = this.state;
|
||||||
|
@ -284,9 +395,12 @@ class SecurityDialog extends PureComponent<Props, State> {
|
||||||
if (typeof _locked === 'undefined') {
|
if (typeof _locked === 'undefined') {
|
||||||
return (
|
return (
|
||||||
<TextInput
|
<TextInput
|
||||||
|
autoFocus = { true }
|
||||||
onChangeText = { this._onChangeText }
|
onChangeText = { this._onChangeText }
|
||||||
placeholder = { t('lobby.passwordField') }
|
placeholder = { t('lobby.passwordField') }
|
||||||
style = { _securityDialogStyles.field }
|
placeholderTextColor = { BaseTheme.palette.text03 }
|
||||||
|
selectionColor = { BaseTheme.palette.action03Active }
|
||||||
|
style = { styles.passwordInput }
|
||||||
underlineColorAndroid = { FIELD_UNDERLINE }
|
underlineColorAndroid = { FIELD_UNDERLINE }
|
||||||
value = { passwordInputValue }
|
value = { passwordInputValue }
|
||||||
{ ...textInputProps } />
|
{ ...textInputProps } />
|
||||||
|
@ -294,13 +408,14 @@ class SecurityDialog extends PureComponent<Props, State> {
|
||||||
} else if (_locked) {
|
} else if (_locked) {
|
||||||
if (_locked === LOCKED_LOCALLY && typeof _password !== 'undefined') {
|
if (_locked === LOCKED_LOCALLY && typeof _password !== 'undefined') {
|
||||||
return (
|
return (
|
||||||
<TextInput
|
<View style = { styles.savedPasswordContainer }>
|
||||||
onChangeText = { this._onChangeText }
|
<Text style = { styles.savedPasswordLabel }>
|
||||||
placeholder = { _password }
|
{ t('info.password') }
|
||||||
style = { _securityDialogStyles.field }
|
</Text>
|
||||||
underlineColorAndroid = { FIELD_UNDERLINE }
|
<Text style = { styles.savedPassword }>
|
||||||
value = { passwordInputValue }
|
{ passwordInputValue }
|
||||||
{ ...textInputProps } />
|
</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}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_onToggleRoomLock() {
|
_onAddPassword() {
|
||||||
const { _isModerator, _locked, dispatch } = this.props;
|
|
||||||
const { showElement } = this.state;
|
const { showElement } = this.state;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
showElement: !showElement
|
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.
|
* Submits value typed in text input.
|
||||||
*
|
*
|
||||||
* @returns {boolean} False because we do not want to hide this
|
* @returns {void}
|
||||||
* dialog/prompt as the hiding will be handled inside endRoomLockRequest
|
|
||||||
* after setting the password is resolved.
|
|
||||||
*/
|
*/
|
||||||
_onSubmit() {
|
_onSubmit() {
|
||||||
const {
|
const {
|
||||||
|
@ -406,8 +539,6 @@ class SecurityDialog extends PureComponent<Props, State> {
|
||||||
const { passwordInputValue } = this.state;
|
const { passwordInputValue } = this.state;
|
||||||
|
|
||||||
dispatch(endRoomLockRequest(_conference, passwordInputValue));
|
dispatch(endRoomLockRequest(_conference, passwordInputValue));
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,8 +567,7 @@ function _mapStateToProps(state: Object): Object {
|
||||||
_lockedConference: Boolean(conference && locked),
|
_lockedConference: Boolean(conference && locked),
|
||||||
_password: password,
|
_password: password,
|
||||||
_passwordNumberOfDigits: roomPasswordNumberOfDigits,
|
_passwordNumberOfDigits: roomPasswordNumberOfDigits,
|
||||||
_roomLockSwitchVisible: visible,
|
_roomPasswordControls: visible
|
||||||
_securityDialogStyles: ColorSchemeRegistry.get(state, 'SecurityDialog')
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
<Dialog
|
||||||
hideCancelButton = { true }
|
hideCancelButton = { true }
|
||||||
submitDisabled = { true }
|
submitDisabled = { true }
|
||||||
titleKey = 'security.securityOptions'
|
titleKey = 'security.header'
|
||||||
width = { 'small' }>
|
width = { 'small' }>
|
||||||
<div className = 'security-dialog'>
|
<div className = 'security-dialog'>
|
||||||
<LobbySection />
|
<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 = () => (
|
const SpeakerStats = () => (
|
||||||
<JitsiScreen
|
<JitsiScreen
|
||||||
hasTabNavigator = { false }
|
|
||||||
style = { style.speakerStatsContainer }>
|
style = { style.speakerStatsContainer }>
|
||||||
<SpeakerStatsLabels />
|
<SpeakerStatsLabels />
|
||||||
<SpeakerStatsList />
|
<SpeakerStatsList />
|
||||||
|
|
|
@ -13,7 +13,8 @@ import { ParticipantsPaneButton } from '../../../participants-pane/components/na
|
||||||
import { ReactionMenu } from '../../../reactions/components';
|
import { ReactionMenu } from '../../../reactions/components';
|
||||||
import { isReactionsEnabled } from '../../../reactions/functions.any';
|
import { isReactionsEnabled } from '../../../reactions/functions.any';
|
||||||
import { LiveStreamButton, RecordButton } from '../../../recording';
|
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 { SharedVideoButton } from '../../../shared-video/components';
|
||||||
import SpeakerStatsButton from '../../../speaker-stats/components/native/SpeakerStatsButton';
|
import SpeakerStatsButton from '../../../speaker-stats/components/native/SpeakerStatsButton';
|
||||||
import { ClosedCaptionButton } from '../../../subtitles';
|
import { ClosedCaptionButton } from '../../../subtitles';
|
||||||
|
|
|
@ -54,7 +54,7 @@ import {
|
||||||
ShareAudioButton,
|
ShareAudioButton,
|
||||||
startScreenShareFlow
|
startScreenShareFlow
|
||||||
} from '../../../screen-share/';
|
} 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 { SettingsButton } from '../../../settings';
|
||||||
import { SharedVideoButton } from '../../../shared-video/components';
|
import { SharedVideoButton } from '../../../shared-video/components';
|
||||||
import { SpeakerStatsButton } from '../../../speaker-stats/components/web';
|
import { SpeakerStatsButton } from '../../../speaker-stats/components/web';
|
||||||
|
|
Loading…
Reference in New Issue