Skip to content

Commit

Permalink
Merge pull request #31 from GetStream/vishal/message-actions
Browse files Browse the repository at this point in the history
Restricting message actions
  • Loading branch information
vishalnarkhede authored Jul 20, 2019
2 parents 80a98e3 + 4def484 commit 1a8af56
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 47 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## [0.6.14] 2019-07-20

- Adding prop `messageActions` to MessageList

## [0.6.13] 2019-07-18

- Adding prop function `onChannelUpdated` as callback for event `channel.updated`
Expand Down
3 changes: 3 additions & 0 deletions src/components/Message.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import PropTypes from 'prop-types';
import { Attachment } from './Attachment';

import deepequal from 'deep-equal';
import { MESSAGE_ACTIONS } from '../utils';

// import diff from 'shallow-diff';

/**
Expand Down Expand Up @@ -49,6 +51,7 @@ export class Message extends Component {
groupStyles: [],
Attachment,
editing: false,
messageActions: Object.keys(MESSAGE_ACTIONS),
};

shouldComponentUpdate(nextProps) {
Expand Down
55 changes: 32 additions & 23 deletions src/components/MessageActionsBox.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { MESSAGE_ACTIONS } from '../utils';

/**
* MessageActionsBox - A component for taking action on a message
Expand Down Expand Up @@ -58,7 +59,7 @@ export class MessageActionsBox extends React.Component {
}

render() {
const { Message, message } = this.props;
const { Message, message, messageActions } = this.props;
return (
<div
className={`str-chat__message-actions-box
Expand All @@ -69,28 +70,36 @@ export class MessageActionsBox extends React.Component {
ref={this.actionsBoxRef}
>
<ul className="str-chat__message-actions-list">
{Message.isMyMessage && !Message.isMyMessage(message) && (
<button onClick={Message.handleFlag}>
<li className="str-chat__message-actions-list-item">Flag</li>
</button>
)}
{Message.isMyMessage && !Message.isMyMessage(message) && (
<button onClick={Message.handleMute}>
<li className="str-chat__message-actions-list-item">Mute</li>
</button>
)}
{Message.canEditMessage && Message.canEditMessage(message) && (
<button onClick={Message.handleEdit}>
<li className="str-chat__message-actions-list-item">
Edit Message
</li>
</button>
)}
{Message.canDeleteMessage && Message.canDeleteMessage(message) && (
<button onClick={Message.handleDelete}>
<li className="str-chat__message-actions-list-item">Delete</li>
</button>
)}
{Message.isMyMessage &&
!Message.isMyMessage(message) &&
messageActions.indexOf(MESSAGE_ACTIONS.edit) > -1 && (
<button onClick={Message.handleFlag}>
<li className="str-chat__message-actions-list-item">Flag</li>
</button>
)}
{Message.isMyMessage &&
!Message.isMyMessage(message) &&
messageActions.indexOf(MESSAGE_ACTIONS.mute) > -1 && (
<button onClick={Message.handleMute}>
<li className="str-chat__message-actions-list-item">Mute</li>
</button>
)}
{Message.canEditMessage &&
Message.canEditMessage(message) &&
messageActions.indexOf(MESSAGE_ACTIONS.edit) > -1 && (
<button onClick={Message.handleEdit}>
<li className="str-chat__message-actions-list-item">
Edit Message
</li>
</button>
)}
{Message.canDeleteMessage &&
Message.canDeleteMessage(message) &&
messageActions.indexOf(MESSAGE_ACTIONS.delete) > -1 && (
<button onClick={Message.handleDelete}>
<li className="str-chat__message-actions-list-item">Delete</li>
</button>
)}
</ul>
</div>
);
Expand Down
5 changes: 5 additions & 0 deletions src/components/MessageList.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { DateSeparator } from './DateSeparator';
import { EventComponent } from './EventComponent';
import { KEY_CODES } from './AutoCompleteTextarea';
import deepequal from 'deep-equal';
import { MESSAGE_ACTIONS } from '../utils';

/**
* MessageList - The message list components renders a list of messages
Expand Down Expand Up @@ -49,12 +50,15 @@ class MessageList extends PureComponent {
noGroupByUser: PropTypes.bool,
/** render HTML instead of markdown. Posting HTML is only allowed server-side */
unsafeHTML: PropTypes.bool,
/** Array of allowed actions on message. e.g. ['edit', 'delete', 'mute', 'flag'] */
messageActions: PropTypes.oneOfType([PropTypes.bool, PropTypes.array]),
};

static defaultProps = {
dateSeparator: DateSeparator,
unsafeHTML: false,
noGroupByUser: false,
messageActions: Object.keys(MESSAGE_ACTIONS),
};

connectionChanged = (event) => {
Expand Down Expand Up @@ -535,6 +539,7 @@ class MessageList extends PureComponent {
Attachment={this.props.Attachment}
onMentionsClick={this.props.onMentionsClick}
onMentionsHover={this.props.onMentionsHover}
messageActions={this.props.messageActions}
/>
</li>,
);
Expand Down
58 changes: 34 additions & 24 deletions src/components/MessageSimple.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,38 @@ export class MessageSimple extends PureComponent {
}
};

renderMessageActions = () => {
if (!this.props.messageActions || this.props.messageActions.length === 0) {
return;
}

return (
<div
onClick={this._onClickOptionsAction}
className="str-chat__message-simple__actions__action str-chat__message-simple__actions__action--options"
>
<MessageActionsBox
Message={this.props.Message}
open={this.state.actionsBoxOpen}
message={this.props.message}
messageListRect={this.props.messageListRect}
mine={this.isMine()}
messageActions={this.props.messageActions}
/>
<svg
width="11"
height="4"
viewBox="0 0 11 4"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M1.5 3a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z"
fillRule="nonzero"
/>
</svg>
</div>
);
};
renderOptions() {
if (
this.props.message.type === 'error' ||
Expand All @@ -214,29 +246,7 @@ export class MessageSimple extends PureComponent {
if (this.isMine()) {
return (
<div className="str-chat__message-simple__actions">
<div
onClick={this._onClickOptionsAction}
className="str-chat__message-simple__actions__action str-chat__message-simple__actions__action--options"
>
<MessageActionsBox
Message={this.props.Message}
open={this.state.actionsBoxOpen}
message={this.props.message}
messageListRect={this.props.messageListRect}
mine={this.isMine()}
/>
<svg
width="11"
height="4"
viewBox="0 0 11 4"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M1.5 3a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z"
fillRule="nonzero"
/>
</svg>
</div>
{this.renderMessageActions()}
{!this.props.threadList && this.props.channelConfig.replies && (
<div
onClick={this.props.openThread}
Expand Down Expand Up @@ -358,7 +368,7 @@ export class MessageSimple extends PureComponent {
<React.Fragment>
<div
key={message.id}
className={`${messageClasses} str-chat__message--deleted`}
className={`${messageClasses} str-chat__message--deleted ${message.type} `}
>
<div className="str-chat__message--deleted-inner">
This message was deleted...
Expand Down
7 changes: 7 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,10 @@ export const smartRender = (ElementOrComponentOrLiteral, props, fallback) => {
}
return <ComponentOrLiteral {...props} />;
};

export const MESSAGE_ACTIONS = {
edit: 'edit',
delete: 'delete',
flag: 'flag',
mute: 'mute',
};

0 comments on commit 1a8af56

Please sign in to comment.