Skip to content

Commit

Permalink
msg action sheet: Add 'Reply with mention' option.
Browse files Browse the repository at this point in the history
Adds the reply with mention featrue, that populates the compose box
message input with an @-mention, the topic input (if present) with
the topic of the message and shows the keyboard.

Fixes: #3436
  • Loading branch information
agrawal-d committed Jul 22, 2020
1 parent 9b84434 commit 318e8d5
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 15 deletions.
11 changes: 11 additions & 0 deletions src/chat/ChatScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type State = {|

class ChatScreen extends PureComponent<Props, State> {
context: Context;
composeBox: React$ElementRef<typeof ComposeBox> = React.createRef();

state = {
editMessage: null,
Expand All @@ -55,6 +56,14 @@ class ChatScreen extends PureComponent<Props, State> {
this.setState({ editMessage: null });
};

replyWithMention = (fullName: string, senderId: number, topic?: string) => {
if (this.composeBox.current !== null) {
this.composeBox.current
.getWrappedInstance()
.handleReplyWithMention(fullName, senderId, topic);
}
};

render() {
const { styles: contextStyles } = this.context;
const { fetching, haveNoMessages, loading, navigation } = this.props;
Expand All @@ -81,13 +90,15 @@ class ChatScreen extends PureComponent<Props, State> {
narrow={narrow}
showMessagePlaceholders={showMessagePlaceholders}
startEditMessage={this.startEditMessage}
replyWithMention={this.replyWithMention}
/>
)}
{showComposeBox && (
<ComposeBox
narrow={narrow}
editMessage={editMessage}
completeEditMessage={this.completeEditMessage}
ref={this.composeBox}
/>
)}
</KeyboardAvoider>
Expand Down
41 changes: 29 additions & 12 deletions src/compose/ComposeBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Platform, View, TextInput, findNodeHandle } from 'react-native';
import type { LayoutEvent } from 'react-native/Libraries/Types/CoreEventTypes';
import TextInputReset from 'react-native-text-input-reset';

import { connect } from 'react-redux';
import type {
Auth,
Context,
Expand All @@ -14,7 +15,6 @@ import type {
Dispatch,
Dimensions,
} from '../types';
import { connect } from '../react-redux';
import {
addToOutbox,
draftUpdate,
Expand Down Expand Up @@ -272,6 +272,17 @@ class ComposeBox extends PureComponent<Props, State> {
}
};

handleReplyWithMention = (fullName: string, senderId: number, topic?: string) => {
this.setState(state => ({
...state,
message: `@**${fullName}|${senderId}** ${state.message}`,
topic: topic !== undefined ? topic : state.topic,
}));
if (this.messageInput) {
this.messageInput.focus();
}
};

UNSAFE_componentWillReceiveProps(nextProps: Props) {
if (nextProps.editMessage !== this.props.editMessage) {
const topic =
Expand Down Expand Up @@ -427,14 +438,20 @@ class ComposeBox extends PureComponent<Props, State> {
}
}

export default connect<SelectorProps, _, _>((state, props) => ({
auth: getAuth(state),
ownEmail: getOwnEmail(state),
usersByEmail: getActiveUsersByEmail(state),
safeAreaInsets: getSession(state).safeAreaInsets,
isAdmin: getIsAdmin(state),
isAnnouncementOnly: getIsActiveStreamAnnouncementOnly(state, props.narrow),
isSubscribed: getIsActiveStreamSubscribed(state, props.narrow),
draft: getDraftForNarrow(state, props.narrow),
lastMessageTopic: getLastMessageTopic(state, props.narrow),
}))(ComposeBox);
// $FlowFixMe our connect wrapper does not yet support the 'withRef' option.
export default connect<SelectorProps, _, _>(
(state, props) => ({
auth: getAuth(state),
ownEmail: getOwnEmail(state),
usersByEmail: getActiveUsersByEmail(state),
safeAreaInsets: getSession(state).safeAreaInsets,
isAdmin: getIsAdmin(state),
isAnnouncementOnly: getIsActiveStreamAnnouncementOnly(state, props.narrow),
isSubscribed: getIsActiveStreamSubscribed(state, props.narrow),
draft: getDraftForNarrow(state, props.narrow),
lastMessageTopic: getLastMessageTopic(state, props.narrow),
}),
null,
null,
{ withRef: true },
)(ComposeBox);
26 changes: 26 additions & 0 deletions src/message/messageActionSheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
isPrivateOrGroupNarrow,
isStreamOrTopicNarrow,
isTopicNarrow,
isSameNarrow,
} from '../utils/narrow';
import { isTopicMuted } from '../utils/message';
import * as api from '../api';
Expand All @@ -42,8 +43,10 @@ type ButtonDescription = {
message: Message | Outbox,
subscriptions: Subscription[],
dispatch: Dispatch,
narrow: Narrow,
_: GetText,
startEditMessage: (editMessage: EditMessage) => void,
replyWithMention: (fullName: string, senderId: number, topic?: string) => void,
}): void | Promise<void>,
title: string,

Expand All @@ -63,6 +66,23 @@ const reply = ({ message, dispatch, ownEmail }) => {
reply.title = 'Reply';
reply.errorMessage = 'Failed to reply';

const mentionAndReply = ({ message, ownEmail, narrow, replyWithMention }) => {
if (message.isOutbox) {
logging.warn('Attempted "Reply with mention" for outbox message');
return;
}

const messageNarrow = getNarrowFromMessage(message, ownEmail);
if (!isSameNarrow(messageNarrow, narrow)) {
replyWithMention(message.sender_full_name, message.sender_id, message.subject);
return;
}

replyWithMention(message.sender_full_name, message.sender_id);
};
mentionAndReply.title = 'Reply with mention';
mentionAndReply.errorMessage = 'Failed to reply with mention';

const copyToClipboard = async ({ _, auth, message }) => {
const rawMessage = message.isOutbox
? message.markdownContent
Expand Down Expand Up @@ -208,6 +228,7 @@ const allButtonsRaw = {
// For messages
addReaction,
reply,
mentionAndReply,
copyToClipboard,
shareMessage,
editMessage,
Expand Down Expand Up @@ -297,6 +318,9 @@ export const constructMessageActionButtons = ({
if (!isTopicNarrow(narrow) && !isPrivateOrGroupNarrow(narrow)) {
buttons.push('reply');
}
if (isStreamOrTopicNarrow(narrow) || isPrivateOrGroupNarrow(narrow)) {
buttons.push('mentionAndReply');
}
if (messageNotDeleted(message)) {
buttons.push('copyToClipboard');
buttons.push('shareMessage');
Expand Down Expand Up @@ -352,6 +376,8 @@ export const showActionSheet = (
callbacks: {|
dispatch: Dispatch,
startEditMessage: (editMessage: EditMessage) => void,
replyWithMention: (fullName: string, senderId: number, topic?: string) => void,

_: GetText,
|},
params: ConstructSheetParams<>,
Expand Down
1 change: 1 addition & 0 deletions src/webview/MessageList.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ export type Props = $ReadOnly<{|
narrow: Narrow,
showMessagePlaceholders: boolean,
startEditMessage: (editMessage: EditMessage) => void,
replyWithMention: (fullName: string, senderId: number, topic?: string) => void,

dispatch: Dispatch,
...SelectorProps,
Expand Down
12 changes: 10 additions & 2 deletions src/webview/webViewEventHandlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ type Props = $ReadOnly<{
narrow: Narrow,
showActionSheetWithOptions: ShowActionSheetWithOptions,
startEditMessage: (editMessage: EditMessage) => void,
replyWithMention: (fullName: string, senderId: number, topic?: string) => void,
}>;

const fetchMore = (props: Props, event: MessageListEventScroll) => {
Expand Down Expand Up @@ -195,11 +196,18 @@ const handleLongPress = (
if (!message) {
return;
}
const { dispatch, showActionSheetWithOptions, backgroundData, narrow, startEditMessage } = props;
const {
dispatch,
showActionSheetWithOptions,
backgroundData,
narrow,
startEditMessage,
replyWithMention,
} = props;
showActionSheet(
target === 'header',
showActionSheetWithOptions,
{ dispatch, startEditMessage, _ },
{ dispatch, startEditMessage, replyWithMention, _ },
{ backgroundData, message, narrow },
);
};
Expand Down
4 changes: 3 additions & 1 deletion static/translations/messages_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"Enter a password": "Enter a password",
"Narrow to conversation": "Narrow to conversation",
"Reply": "Reply",
"Reply with mention": "Reply with mention",
"Add a reaction": "Add a reaction",
"Copy to clipboard": "Copy to clipboard",
"Link copied to clipboard": "Link copied to clipboard",
Expand Down Expand Up @@ -143,6 +144,7 @@
"Network request failed": "Network request failed",
"Failed to add reaction": "Failed to add reaction",
"Failed to reply": "Failed to reply",
"Failed to reply with mention": "Failed to reply with mention",
"Failed to copy message to clipboard": "Failed to copy message to clipboard",
"Failed to share message": "Failed to share message",
"Failed to edit message": "Failed to edit message",
Expand Down Expand Up @@ -220,4 +222,4 @@
"🤒 Out sick": "🤒 Out sick",
"🌴 Vacationing": "🌴 Vacationing",
"🏠 Working remotely": "🏠 Working remotely"
}
}

0 comments on commit 318e8d5

Please sign in to comment.