mirror of https://github.com/jitsi/jitsi-meet
parent
035f720a50
commit
b85cd2348f
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,70 @@ |
||||
// @flow
|
||||
|
||||
import { openDialog } from '../../base/dialog'; |
||||
import { IconCrown } from '../../base/icons'; |
||||
import { |
||||
getParticipantById, |
||||
isLocalParticipantModerator, |
||||
isParticipantModerator |
||||
} from '../../base/participants'; |
||||
import { AbstractButton } from '../../base/toolbox'; |
||||
import type { AbstractButtonProps } from '../../base/toolbox'; |
||||
|
||||
import { GrantModeratorDialog } from '.'; |
||||
|
||||
export type Props = AbstractButtonProps & { |
||||
|
||||
/** |
||||
* The redux {@code dispatch} function. |
||||
*/ |
||||
dispatch: Function, |
||||
|
||||
/** |
||||
* The ID of the participant for whom to grant moderator status. |
||||
*/ |
||||
participantID: string, |
||||
|
||||
/** |
||||
* The function to be used to translate i18n labels. |
||||
*/ |
||||
t: Function |
||||
}; |
||||
|
||||
/** |
||||
* An abstract remote video menu button which kicks the remote participant. |
||||
*/ |
||||
export default class AbstractGrantModeratorButton extends AbstractButton<Props, *> { |
||||
accessibilityLabel = 'toolbar.accessibilityLabel.grantModerator'; |
||||
icon = IconCrown; |
||||
label = 'videothumbnail.grantModerator'; |
||||
|
||||
/** |
||||
* Handles clicking / pressing the button, and kicks the participant. |
||||
* |
||||
* @private |
||||
* @returns {void} |
||||
*/ |
||||
_handleClick() { |
||||
const { dispatch, participantID } = this.props; |
||||
|
||||
dispatch(openDialog(GrantModeratorDialog, { participantID })); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Function that maps parts of Redux state tree into component props. |
||||
* |
||||
* @param {Object} state - Redux state. |
||||
* @param {Object} ownProps - Properties of component. |
||||
* @private |
||||
* @returns {{ |
||||
* visible: boolean |
||||
* }} |
||||
*/ |
||||
export function _mapStateToProps(state: Object, ownProps: Props) { |
||||
const { participantID } = ownProps; |
||||
|
||||
return { |
||||
visible: isLocalParticipantModerator(state) && !isParticipantModerator(getParticipantById(state, participantID)) |
||||
}; |
||||
} |
@ -0,0 +1,66 @@ |
||||
// @flow
|
||||
|
||||
import { Component } from 'react'; |
||||
|
||||
import { |
||||
createRemoteVideoMenuButtonEvent, |
||||
sendAnalytics |
||||
} from '../../analytics'; |
||||
import { grantModerator } from '../../base/participants'; |
||||
|
||||
type Props = { |
||||
|
||||
/** |
||||
* The Redux dispatch function. |
||||
*/ |
||||
dispatch: Function, |
||||
|
||||
/** |
||||
* The ID of the remote participant to be granted moderator rights. |
||||
*/ |
||||
participantID: string, |
||||
|
||||
/** |
||||
* Function to translate i18n labels. |
||||
*/ |
||||
t: Function |
||||
}; |
||||
|
||||
/** |
||||
* Abstract dialog to confirm granting moderator to a participant. |
||||
*/ |
||||
export default class AbstractGrantModeratorDialog |
||||
extends Component<Props> { |
||||
/** |
||||
* Initializes a new {@code AbstractGrantModeratorDialog} instance. |
||||
* |
||||
* @inheritdoc |
||||
*/ |
||||
constructor(props: Props) { |
||||
super(props); |
||||
|
||||
this._onSubmit = this._onSubmit.bind(this); |
||||
} |
||||
|
||||
_onSubmit: () => boolean; |
||||
|
||||
/** |
||||
* Callback for the confirm button. |
||||
* |
||||
* @private |
||||
* @returns {boolean} - True (to note that the modal should be closed). |
||||
*/ |
||||
_onSubmit() { |
||||
const { dispatch, participantID } = this.props; |
||||
|
||||
sendAnalytics(createRemoteVideoMenuButtonEvent( |
||||
'grant.moderator.button', |
||||
{ |
||||
'participant_id': participantID |
||||
})); |
||||
|
||||
dispatch(grantModerator(participantID)); |
||||
|
||||
return true; |
||||
} |
||||
} |
@ -0,0 +1,9 @@ |
||||
// @flow
|
||||
|
||||
import { translate } from '../../../base/i18n'; |
||||
import { connect } from '../../../base/redux'; |
||||
import AbstractGrantModeratorButton, { |
||||
_mapStateToProps |
||||
} from '../AbstractGrantModeratorButton'; |
||||
|
||||
export default translate(connect(_mapStateToProps)(AbstractGrantModeratorButton)); |
@ -0,0 +1,32 @@ |
||||
// @flow
|
||||
|
||||
import React from 'react'; |
||||
|
||||
import { ConfirmDialog } from '../../../base/dialog'; |
||||
import { translate } from '../../../base/i18n'; |
||||
import { connect } from '../../../base/redux'; |
||||
import AbstractGrantModeratorDialog |
||||
from '../AbstractGrantModeratorDialog'; |
||||
|
||||
/** |
||||
* Dialog to confirm a remote participant kick action. |
||||
*/ |
||||
class GrantModeratorDialog extends AbstractGrantModeratorDialog { |
||||
/** |
||||
* Implements React's {@link Component#render()}. |
||||
* |
||||
* @inheritdoc |
||||
* @returns {ReactElement} |
||||
*/ |
||||
render() { |
||||
return ( |
||||
<ConfirmDialog |
||||
contentKey = 'dialog.grantModeratorDialog' |
||||
onSubmit = { this._onSubmit } /> |
||||
); |
||||
} |
||||
|
||||
_onSubmit: () => boolean; |
||||
} |
||||
|
||||
export default translate(connect()(GrantModeratorDialog)); |
@ -0,0 +1,60 @@ |
||||
/* @flow */ |
||||
|
||||
import React from 'react'; |
||||
|
||||
import { translate } from '../../../base/i18n'; |
||||
import { IconCrown } from '../../../base/icons'; |
||||
import { connect } from '../../../base/redux'; |
||||
import AbstractGrantModeratorButton, { |
||||
_mapStateToProps, |
||||
type Props |
||||
} from '../AbstractGrantModeratorButton'; |
||||
|
||||
import RemoteVideoMenuButton from './RemoteVideoMenuButton'; |
||||
|
||||
declare var interfaceConfig: Object; |
||||
|
||||
/** |
||||
* Implements a React {@link Component} which displays a button for granting |
||||
* moderator to a participant. |
||||
*/ |
||||
class GrantModeratorButton extends AbstractGrantModeratorButton { |
||||
/** |
||||
* Instantiates a new {@code GrantModeratorButton}. |
||||
* |
||||
* @inheritdoc |
||||
*/ |
||||
constructor(props: Props) { |
||||
super(props); |
||||
|
||||
this._handleClick = this._handleClick.bind(this); |
||||
} |
||||
|
||||
/** |
||||
* Implements React's {@link Component#render()}. |
||||
* |
||||
* @inheritdoc |
||||
* @returns {ReactElement} |
||||
*/ |
||||
render() { |
||||
const { participantID, t, visible } = this.props; |
||||
|
||||
if (!visible) { |
||||
return null; |
||||
} |
||||
|
||||
return ( |
||||
<RemoteVideoMenuButton |
||||
buttonText = { t('videothumbnail.grantModerator') } |
||||
displayClass = 'grantmoderatorlink' |
||||
icon = { IconCrown } |
||||
id = { `grantmoderatorlink_${participantID}` } |
||||
// eslint-disable-next-line react/jsx-handler-names
|
||||
onClick = { this._handleClick } /> |
||||
); |
||||
} |
||||
|
||||
_handleClick: () => void |
||||
} |
||||
|
||||
export default translate(connect(_mapStateToProps)(GrantModeratorButton)); |
@ -0,0 +1,38 @@ |
||||
// @flow
|
||||
|
||||
import React from 'react'; |
||||
|
||||
import { Dialog } from '../../../base/dialog'; |
||||
import { translate } from '../../../base/i18n'; |
||||
import { connect } from '../../../base/redux'; |
||||
import AbstractGrantModeratorDialog |
||||
from '../AbstractGrantModeratorDialog'; |
||||
|
||||
/** |
||||
* Dialog to confirm a grant moderator action. |
||||
*/ |
||||
class GrantModeratorDialog extends AbstractGrantModeratorDialog { |
||||
/** |
||||
* Implements React's {@link Component#render()}. |
||||
* |
||||
* @inheritdoc |
||||
* @returns {ReactElement} |
||||
*/ |
||||
render() { |
||||
return ( |
||||
<Dialog |
||||
okKey = 'dialog.Yes' |
||||
onSubmit = { this._onSubmit } |
||||
titleKey = 'dialog.grantModeratorTitle' |
||||
width = 'small'> |
||||
<div> |
||||
{ this.props.t('dialog.grantModeratorDialog') } |
||||
</div> |
||||
</Dialog> |
||||
); |
||||
} |
||||
|
||||
_onSubmit: () => boolean; |
||||
} |
||||
|
||||
export default translate(connect()(GrantModeratorDialog)); |
Loading…
Reference in new issue