Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

ContextMenuMeetingParticipantDetails.js 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // @flow
  2. import React, { useCallback } from 'react';
  3. import { useTranslation } from 'react-i18next';
  4. import { TouchableOpacity, View } from 'react-native';
  5. import { Text } from 'react-native-paper';
  6. import { useDispatch, useSelector } from 'react-redux';
  7. import { Avatar } from '../../../base/avatar';
  8. import { isToolbarButtonEnabled } from '../../../base/config';
  9. import { hideDialog, openDialog } from '../../../base/dialog';
  10. import BottomSheet from '../../../base/dialog/components/native/BottomSheet';
  11. import {
  12. Icon, IconCloseCircle, IconConnectionActive, IconMessage,
  13. IconMicrophoneEmptySlash,
  14. IconMuteEveryoneElse, IconVideoOff
  15. } from '../../../base/icons';
  16. import { isLocalParticipantModerator } from '../../../base/participants';
  17. import { getIsParticipantVideoMuted } from '../../../base/tracks';
  18. import { openChat } from '../../../chat/actions.native';
  19. import {
  20. KickRemoteParticipantDialog,
  21. MuteEveryoneDialog,
  22. MuteRemoteParticipantDialog,
  23. MuteRemoteParticipantsVideoDialog,
  24. VolumeSlider
  25. } from '../../../video-menu';
  26. import styles from './styles';
  27. type Props = {
  28. /**
  29. * Participant reference
  30. */
  31. participant: Object
  32. };
  33. export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props) => {
  34. const dispatch = useDispatch();
  35. const cancel = useCallback(() => dispatch(hideDialog()), [ dispatch ]);
  36. const displayName = p.name;
  37. const isLocalModerator = useSelector(isLocalParticipantModerator);
  38. const isChatButtonEnabled = useSelector(isToolbarButtonEnabled('chat'));
  39. const isParticipantVideoMuted = useSelector(getIsParticipantVideoMuted(p));
  40. const kickRemoteParticipant = useCallback(() => {
  41. dispatch(openDialog(KickRemoteParticipantDialog, {
  42. participantID: p.id
  43. }));
  44. }, [ dispatch, p ]);
  45. const muteAudio = useCallback(() => {
  46. dispatch(openDialog(MuteRemoteParticipantDialog, {
  47. participantID: p.id
  48. }));
  49. }, [ dispatch, p ]);
  50. const muteEveryoneElse = useCallback(() => {
  51. dispatch(openDialog(MuteEveryoneDialog, {
  52. exclude: [ p.id ]
  53. }));
  54. }, [ dispatch, p ]);
  55. const muteVideo = useCallback(() => {
  56. dispatch(openDialog(MuteRemoteParticipantsVideoDialog, {
  57. participantID: p.id
  58. }));
  59. }, [ dispatch, p ]);
  60. const sendPrivateMessage = useCallback(() => {
  61. dispatch(openChat(p));
  62. }, [ dispatch, p ]);
  63. const { t } = useTranslation();
  64. return (
  65. <BottomSheet
  66. onCancel = { cancel }
  67. style = { styles.contextMenuMore }>
  68. <View
  69. style = { styles.contextMenuItemSection }>
  70. <Avatar
  71. className = 'participant-avatar'
  72. participantId = { p.id }
  73. size = { 24 } />
  74. <View style = { styles.contextMenuItemText }>
  75. <Text style = { styles.contextMenuItemName }>
  76. { displayName }
  77. </Text>
  78. </View>
  79. </View>
  80. {
  81. isLocalModerator
  82. && <TouchableOpacity
  83. onPress = { muteAudio }
  84. style = { styles.contextMenuItem }>
  85. <Icon
  86. size = { 24 }
  87. src = { IconMicrophoneEmptySlash }
  88. style = { styles.contextMenuItemIcon } />
  89. <Text style = { styles.contextMenuItemText }>
  90. { t('participantsPane.actions.mute') }
  91. </Text>
  92. </TouchableOpacity>
  93. }
  94. {
  95. isLocalModerator
  96. && <TouchableOpacity
  97. onPress = { muteEveryoneElse }
  98. style = { styles.contextMenuItem }>
  99. <Icon
  100. size = { 24 }
  101. src = { IconMuteEveryoneElse }
  102. style = { styles.contextMenuItemIcon } />
  103. <Text style = { styles.contextMenuItemText }>
  104. { t('participantsPane.actions.muteEveryoneElse') }
  105. </Text>
  106. </TouchableOpacity>
  107. }
  108. {
  109. isLocalModerator && (
  110. isParticipantVideoMuted
  111. || <TouchableOpacity
  112. onPress = { muteVideo }
  113. style = { styles.contextMenuItemSection }>
  114. <Icon
  115. size = { 24 }
  116. src = { IconVideoOff }
  117. style = { styles.contextMenuItemIcon } />
  118. <Text style = { styles.contextMenuItemText }>
  119. { t('participantsPane.actions.stopVideo') }
  120. </Text>
  121. </TouchableOpacity>
  122. )
  123. }
  124. {
  125. isLocalModerator
  126. && <TouchableOpacity
  127. onPress = { kickRemoteParticipant }
  128. style = { styles.contextMenuItem }>
  129. <Icon
  130. size = { 24 }
  131. src = { IconCloseCircle }
  132. style = { styles.contextMenuItemIcon } />
  133. <Text style = { styles.contextMenuItemText }>
  134. { t('videothumbnail.kick') }
  135. </Text>
  136. </TouchableOpacity>
  137. }
  138. {
  139. isChatButtonEnabled
  140. && <TouchableOpacity
  141. onPress = { sendPrivateMessage }
  142. style = { styles.contextMenuItem }>
  143. <Icon
  144. size = { 24 }
  145. src = { IconMessage }
  146. style = { styles.contextMenuItemIcon } />
  147. <Text style = { styles.contextMenuItemText }>
  148. { t('toolbar.accessibilityLabel.privateMessage') }
  149. </Text>
  150. </TouchableOpacity>
  151. }
  152. <TouchableOpacity
  153. style = { styles.contextMenuItemSection }>
  154. <Icon
  155. size = { 24 }
  156. src = { IconConnectionActive }
  157. style = { styles.contextMenuItemIcon } />
  158. <Text style = { styles.contextMenuItemText }>{ t('participantsPane.actions.networkStats') }</Text>
  159. </TouchableOpacity>
  160. <VolumeSlider />
  161. </BottomSheet>
  162. );
  163. };