This repository has been archived by the owner on Mar 13, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
[28725] Add call button #5715
Merged
Merged
[28725] Add call button #5715
Changes from 21 commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
10cd5d7
Add Call dropdown for plugins
larkox 91f6c7a
Update i18n
larkox 01ea0de
Merge branch 'master' into AddCallButton
larkox 4f9dcfa
Remove plugings channel header call and reuse channel header plug
larkox 25c98a3
Fix tooltip and i18n error
larkox 1233224
Merge branch 'master' into AddCallButton
larkox b4a2372
Add minimum required version and remove unneeded react fragment
larkox ab0dd85
Merge branch 'master' into AddCallButton
larkox 2796a9f
Add call button to post
larkox 2ab1847
Extract i18n
larkox 8f88964
Change icon by camera icon
larkox 7fe77e2
Remove header button for calls
larkox 3000715
Merge branch 'master' into AddCallButton
larkox e18602e
Fix tests and remove changes from the header button
larkox 55b44ce
Merge branch 'master' into AddCallButton
larkox 5d5976d
Fix lint
larkox a25e3e3
Update i18n
larkox b8dbbec
Merge branch 'master' into AddCallButton
larkox 8cad316
Remove unneeded divs, change CameraIcon to functional component, simp…
larkox 1b4e814
Remove channel header references, fix lint and remove unused style
larkox 89392ec
Fix bug
larkox 3cbc470
Change callbutton to functional component
larkox eb237df
Merge branch 'master' into AddCallButton
larkox e4c2236
Merge branch 'master' into AddCallButton
larkox 77534a7
Merge branch 'master' into AddCallButton
larkox 01bc11a
Fix CSS
larkox 746f5e3
Merge branch 'master' into AddCallButton
larkox a516b6c
Merge branch 'master' into AddCallButton
larkox File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||
// See LICENSE.txt for license information. | ||
|
||
import PropTypes from 'prop-types'; | ||
import React, {PureComponent} from 'react'; | ||
import {injectIntl} from 'react-intl'; | ||
|
||
import {intlShape} from 'utils/react_intl'; | ||
|
||
import MenuWrapper from 'components/widgets/menu/menu_wrapper'; | ||
import Menu from 'components/widgets/menu/menu'; | ||
import CameraIcon from 'components/widgets/icons/camera_icon'; | ||
|
||
const customStyles = { | ||
left: 'inherit', | ||
right: 0, | ||
bottom: '100%', | ||
top: 'auto', | ||
}; | ||
|
||
class CallButton extends PureComponent { | ||
static propTypes = { | ||
hmhealey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
currentChannel: PropTypes.object.isRequired, | ||
channelMember: PropTypes.object, | ||
intl: intlShape.isRequired, | ||
locale: PropTypes.string.isRequired, | ||
pluginCallMethods: PropTypes.arrayOf(PropTypes.object), | ||
}; | ||
|
||
static defaultProps = { | ||
pluginCallMethods: [], | ||
}; | ||
|
||
constructor(props) { | ||
super(props); | ||
this.state = { | ||
menuOpen: false, | ||
}; | ||
} | ||
|
||
toggleMenu = (open) => { | ||
this.setState({menuOpen: open}); | ||
} | ||
|
||
render() { | ||
const {formatMessage} = this.props.intl; | ||
|
||
let bodyAction; | ||
|
||
if (this.props.pluginCallMethods.length === 0) { | ||
bodyAction = null; | ||
} else if (this.props.pluginCallMethods.length === 1) { | ||
const item = this.props.pluginCallMethods[0]; | ||
bodyAction = ( | ||
<button | ||
type='button' | ||
className='style--none post-action icon icon--attachment' | ||
onClick={() => { | ||
if (item.action) { | ||
item.action(this.props.currentChannel, this.props.channelMember); | ||
} | ||
}} | ||
onTouchEnd={() => { | ||
if (item.action) { | ||
item.action(this.props.currentChannel, this.props.channelMember); | ||
} | ||
}} | ||
> | ||
{item.icon} | ||
</button> | ||
); | ||
} else { | ||
const pluginCallMethods = this.props.pluginCallMethods.map((item) => { | ||
return ( | ||
<li | ||
key={item.id} | ||
onClick={(e) => { | ||
e.preventDefault(); | ||
if (item.action) { | ||
item.action(this.props.currentChannel, this.props.channelMember); | ||
} | ||
this.setState({menuOpen: false}); | ||
}} | ||
> | ||
<a href='#'> | ||
hmhealey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<span className='mr-2'> | ||
{item.icon} | ||
</span> | ||
{item.dropdownText} | ||
</a> | ||
</li> | ||
); | ||
}); | ||
bodyAction = ( | ||
<MenuWrapper> | ||
<button | ||
type='button' | ||
className='style--none post-action' | ||
> | ||
<div | ||
className='icon icon--attachment' | ||
> | ||
<CameraIcon className='d-flex'/> | ||
</div> | ||
</button> | ||
<Menu | ||
id='callOptions' | ||
openLeft={true} | ||
openUp={true} | ||
ariaLabel={formatMessage({id: 'call_button.menuAriaLabel', defaultMessage: 'Call type selector'})} | ||
customStyles={customStyles} | ||
> | ||
{pluginCallMethods} | ||
</Menu> | ||
</MenuWrapper> | ||
); | ||
} | ||
|
||
return bodyAction; | ||
} | ||
} | ||
|
||
const wrappedComponent = injectIntl(CallButton); | ||
wrappedComponent.displayName = 'injectIntl(CallButton)'; | ||
export default wrappedComponent; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||
// See LICENSE.txt for license information. | ||
|
||
import {connect} from 'react-redux'; | ||
|
||
import {getCurrentChannel, getMyCurrentChannelMembership} from 'mattermost-redux/selectors/entities/channels'; | ||
|
||
import {getCurrentLocale} from 'selectors/i18n'; | ||
|
||
import CallButton from './call_button.jsx'; | ||
|
||
function mapStateToProps(state) { | ||
return { | ||
currentChannel: getCurrentChannel(state), | ||
locale: getCurrentLocale(state), | ||
pluginCallMethods: state.plugins.components.CallButton, | ||
channelMember: getMyCurrentChannelMembership(state), | ||
}; | ||
} | ||
|
||
export default connect(mapStateToProps)(CallButton); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||
// See LICENSE.txt for license information. | ||
|
||
import React from 'react'; | ||
import {useIntl} from 'react-intl'; | ||
|
||
export default function CameraIcon(props) { | ||
const intl = useIntl(); | ||
return ( | ||
<span {...props}> | ||
<svg | ||
width='14px' | ||
height='10px' | ||
viewBox='0 0 16 12' | ||
role='img' | ||
aria-label={intl.formatMessage({id: 'generic_icons.camera', defaultMessage: 'Camera Icon'})} | ||
> | ||
<g | ||
stroke='none' | ||
strokeWidth='1' | ||
fill='inherit' | ||
fillRule='evenodd' | ||
> | ||
<g | ||
transform='translate(-696.000000, -34.000000)' | ||
fillRule='nonzero' | ||
fill='inherit' | ||
> | ||
<g transform='translate(-1.000000, 0.000000)'> | ||
<g transform='translate(687.000000, 22.000000)'> | ||
<g transform='translate(10.000000, 12.000000)'> | ||
<path d='M15.105,1.447 L12,3 L12,1 C12,0.447 11.553,0 11,0 L1,0 C0.447,0 0,0.447 0,1 L0,11 C0,11.553 0.447,12 1,12 L11,12 C11.553,12 12,11.553 12,11 L12,9 L15.105,10.553 C15.6,10.8 16,10.553 16,10 L16,2 C16,1.447 15.6,1.2 15.105,1.447 Z M12.895,7.211 C12.612,7.07 12.306,7 12,7 L10.5,7 C10.224,7 10,7.224 10,7.5 L10,10 L2,10 L2,2 L10,2 L10,4.5 C10,4.776 10.224,5 10.5,5 L12,5 C12.306,5 12.612,4.93 12.895,4.789 L14,4.236 L14,7.763 L12.895,7.211 Z'/> | ||
</g> | ||
</g> | ||
</g> | ||
</g> | ||
</g> | ||
</svg> | ||
</span> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be a class component? IMO this is a good candidate for a Functional Component.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(0/5) For simplicity, I would keep this as a class component, since it does have state and some (minor) behaviour. We can improve it later.
Nevertheless, if you want it to be a functional component, I can give it a try.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We want to switch to using react hooks with functional components in our codebase and in this case the state can be managed easily with hooks. I suggest the refactor because it would avoid the refactor of another component later. But if the PR is urgent I won't block it. Just a suggestion :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Actually the state was not being used, so it was simpler than I expected.