[NEW] Reply in direct (#4582)
* add translations * implements reply in DM * refactor data e2e * fix ignoreuser e2e * create test for reply in dm * minor tweak Co-authored-by: Reinaldo Neto <47038980+reinaldonetof@users.noreply.github.com> Co-authored-by: Reinaldo Neto <reinaldonetof@hotmail.com>
This commit is contained in:
parent
60c040c396
commit
ac9526fce1
|
@ -17,7 +17,7 @@ import Header, { HEADER_HEIGHT, IHeader } from './Header';
|
|||
import events from '../../lib/methods/helpers/log/events';
|
||||
import { IApplicationState, IEmoji, ILoggedUser, TAnyMessageModel, TSubscriptionModel } from '../../definitions';
|
||||
import { getPermalinkMessage } from '../../lib/methods';
|
||||
import { hasPermission } from '../../lib/methods/helpers';
|
||||
import { getRoomTitle, getUidDirectMessage, hasPermission } from '../../lib/methods/helpers';
|
||||
import { Services } from '../../lib/services';
|
||||
|
||||
export interface IMessageActionsProps {
|
||||
|
@ -41,6 +41,7 @@ export interface IMessageActionsProps {
|
|||
deleteMessagePermission?: string[];
|
||||
forceDeleteMessagePermission?: string[];
|
||||
pinMessagePermission?: string[];
|
||||
createDirectMessagePermission?: string[];
|
||||
}
|
||||
|
||||
export interface IMessageActions {
|
||||
|
@ -70,7 +71,8 @@ const MessageActions = React.memo(
|
|||
editMessagePermission,
|
||||
deleteMessagePermission,
|
||||
forceDeleteMessagePermission,
|
||||
pinMessagePermission
|
||||
pinMessagePermission,
|
||||
createDirectMessagePermission
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
|
@ -235,6 +237,23 @@ const MessageActions = React.memo(
|
|||
replyInit(message, false);
|
||||
};
|
||||
|
||||
const handleReplyInDM = async (message: TAnyMessageModel) => {
|
||||
if (message?.u?.username) {
|
||||
const result = await Services.createDirectMessage(message.u.username);
|
||||
if (result.success) {
|
||||
const { room } = result;
|
||||
const params = {
|
||||
rid: room.rid,
|
||||
name: getRoomTitle(room),
|
||||
t: room.t,
|
||||
roomUserId: getUidDirectMessage(room),
|
||||
replyInDM: message
|
||||
};
|
||||
Navigation.replace('RoomView', params);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleStar = async (message: TAnyMessageModel) => {
|
||||
logEvent(message.starred ? events.ROOM_MSG_ACTION_UNSTAR : events.ROOM_MSG_ACTION_STAR);
|
||||
try {
|
||||
|
@ -345,6 +364,15 @@ const MessageActions = React.memo(
|
|||
});
|
||||
}
|
||||
|
||||
// Reply in DM
|
||||
if (room.t !== 'd' && room.t !== 'l' && createDirectMessagePermission) {
|
||||
options.push({
|
||||
title: I18n.t('Reply_in_direct_message'),
|
||||
icon: 'arrow-back',
|
||||
onPress: () => handleReplyInDM(message)
|
||||
});
|
||||
}
|
||||
|
||||
// Edit
|
||||
if (allowEdit(message)) {
|
||||
options.push({
|
||||
|
@ -480,7 +508,8 @@ const mapStateToProps = (state: IApplicationState) => ({
|
|||
editMessagePermission: state.permissions['edit-message'],
|
||||
deleteMessagePermission: state.permissions['delete-message'],
|
||||
forceDeleteMessagePermission: state.permissions['force-delete-message'],
|
||||
pinMessagePermission: state.permissions['pin-message']
|
||||
pinMessagePermission: state.permissions['pin-message'],
|
||||
createDirectMessagePermission: state.permissions['create-d']
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, null, null, { forwardRef: true })(MessageActions);
|
||||
|
|
|
@ -862,6 +862,7 @@
|
|||
"Select_Members": "Select Members",
|
||||
"Also_send_thread_message_to_channel_behavior": "Also send thread message to channel",
|
||||
"Accounts_Default_User_Preferences_alsoSendThreadToChannel_Description": "Allow users to select the Also send to channel behavior",
|
||||
"Reply_in_direct_message": "Reply in Direct Message",
|
||||
"room_archived": "archived room",
|
||||
"room_unarchived": "unarchived room"
|
||||
}
|
|
@ -817,6 +817,7 @@
|
|||
"Select_Members": "Selecionar Membros",
|
||||
"Also_send_thread_message_to_channel_behavior": "Também enviar mensagem do tópico para o canal",
|
||||
"Accounts_Default_User_Preferences_alsoSendThreadToChannel_Description": "Permitir que os usuários selecionem o comportamento Também enviar para o canal",
|
||||
"Reply_in_direct_message": "Responder por mensagem direta",
|
||||
"room_archived": "{{username}} arquivou a sala",
|
||||
"room_unarchived": "{{username}} desarquivou a sala"
|
||||
}
|
|
@ -5,7 +5,7 @@ import { IItem } from '../views/TeamChannelsView';
|
|||
import { IOptionsField } from '../views/NotificationPreferencesView/options';
|
||||
import { IServer } from '../definitions/IServer';
|
||||
import { IAttachment } from '../definitions/IAttachment';
|
||||
import { IMessage, TMessageModel } from '../definitions/IMessage';
|
||||
import { IMessage, TAnyMessageModel, TMessageModel } from '../definitions/IMessage';
|
||||
import { ISubscription, SubscriptionType, TSubscriptionModel } from '../definitions/ISubscription';
|
||||
import { ICannedResponse } from '../definitions/ICannedResponse';
|
||||
import { TDataSelect } from '../definitions/IDataSelect';
|
||||
|
@ -37,6 +37,7 @@ export type ChatsStackParamList = {
|
|||
roomUserId?: string | null;
|
||||
usedCannedResponse?: string;
|
||||
status?: string;
|
||||
replyInDM?: TAnyMessageModel;
|
||||
}
|
||||
| undefined; // Navigates back to RoomView already on stack
|
||||
RoomActionsView: {
|
||||
|
|
|
@ -225,6 +225,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
|||
private retryFindTimeout?: ReturnType<typeof setTimeout>;
|
||||
private messageErrorActions?: IMessageErrorActions | null;
|
||||
private messageActions?: IMessageActions | null;
|
||||
private replyInDM?: TAnyMessageModel;
|
||||
// Type of InteractionManager.runAfterInteractions
|
||||
private didMountInteraction?: {
|
||||
then: (onfulfilled?: (() => any) | undefined, onrejected?: (() => any) | undefined) => Promise<any>;
|
||||
|
@ -259,6 +260,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
|||
this.jumpToMessageId = props.route.params?.jumpToMessageId;
|
||||
this.jumpToThreadId = props.route.params?.jumpToThreadId;
|
||||
const roomUserId = props.route.params?.roomUserId ?? getUidDirectMessage(room);
|
||||
this.replyInDM = props.route.params?.replyInDM;
|
||||
this.state = {
|
||||
joined: true,
|
||||
room,
|
||||
|
@ -332,6 +334,9 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
|||
if (isIOS && this.rid) {
|
||||
this.updateUnreadCount();
|
||||
}
|
||||
if (this.replyInDM) {
|
||||
this.onReplyInit(this.replyInDM, false);
|
||||
}
|
||||
});
|
||||
if (isTablet) {
|
||||
EventEmitter.addEventListener(KEY_COMMAND, this.handleCommands);
|
||||
|
|
|
@ -51,9 +51,11 @@ const data = {
|
|||
detoxpublicprotected: {
|
||||
name: 'detox-public-protected',
|
||||
joinCode: '123'
|
||||
},
|
||||
detoxpublicignore: {
|
||||
name: `detox-public-ignore-${value}`
|
||||
}
|
||||
},
|
||||
userRegularChannels: {
|
||||
detoxpublic: {
|
||||
name: `detox-public-${value}`
|
||||
}
|
||||
},
|
||||
groups: {
|
||||
|
|
|
@ -54,6 +54,11 @@ const data = {
|
|||
joinCode: '123'
|
||||
}
|
||||
},
|
||||
userRegularChannels: {
|
||||
detoxpublic: {
|
||||
name: `detox-public-${value}`
|
||||
}
|
||||
},
|
||||
groups: {
|
||||
private: {
|
||||
name: `detox-private-${value}`
|
||||
|
|
|
@ -53,6 +53,11 @@ const data = {
|
|||
joinCode: '123'
|
||||
}
|
||||
},
|
||||
userRegularChannels: {
|
||||
detoxpublic: {
|
||||
name: `detox-public-${value}`
|
||||
}
|
||||
},
|
||||
groups: {
|
||||
private: {
|
||||
name: `detox-private-${value}`
|
||||
|
|
|
@ -158,6 +158,21 @@ const setup = async () => {
|
|||
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
|
||||
for (const channelKey in data.userRegularChannels) {
|
||||
if (Object.prototype.hasOwnProperty.call(data.userRegularChannels, channelKey)) {
|
||||
const channel = data.userRegularChannels[channelKey as TDataChannels];
|
||||
const {
|
||||
data: {
|
||||
channel: { _id }
|
||||
}
|
||||
} = await createChannelIfNotExists(channel.name);
|
||||
|
||||
if ('joinCode' in channel) {
|
||||
await changeChannelJoinCode(_id, channel.joinCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const groupKey in data.groups) {
|
||||
if (Object.prototype.hasOwnProperty.call(data.groups, groupKey)) {
|
||||
const group = data.groups[groupKey as TDataGroups];
|
||||
|
|
|
@ -13,6 +13,7 @@ import {
|
|||
platformTypes,
|
||||
TTextMatcher
|
||||
} from '../../helpers/app';
|
||||
import { sendMessage } from '../../helpers/data_setup';
|
||||
|
||||
async function navigateToRoom(roomName: string) {
|
||||
await searchRoom(`${roomName}`);
|
||||
|
@ -496,6 +497,37 @@ describe('Room screen', () => {
|
|||
await waitFor(element(by[textMatcher](`${data.random}delete`)).atIndex(0))
|
||||
.toNotExist()
|
||||
.withTimeout(2000);
|
||||
await tapBack();
|
||||
});
|
||||
|
||||
it('should reply in DM to another user', async () => {
|
||||
const channelName = data.userRegularChannels.detoxpublic.name;
|
||||
const stringToReply = 'Message to reply in DM';
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await navigateToRoom(channelName);
|
||||
await sendMessage(data.users.alternate, channelName, stringToReply);
|
||||
await waitFor(element(by[textMatcher](stringToReply)).atIndex(0))
|
||||
.toBeVisible()
|
||||
.withTimeout(3000);
|
||||
await element(by[textMatcher](stringToReply)).atIndex(0).longPress();
|
||||
await waitFor(element(by.id('action-sheet')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await waitFor(element(by[textMatcher]('Reply in Direct Message')).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(6000);
|
||||
await element(by[textMatcher]('Reply in Direct Message')).atIndex(0).tap();
|
||||
await waitFor(element(by.id(`room-view-title-${data.users.alternate.username}`)))
|
||||
.toExist()
|
||||
.withTimeout(6000);
|
||||
await element(by.id('messagebox-input')).replaceText(`${data.random} replied in dm`);
|
||||
await waitFor(element(by.id('messagebox-send-message')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('messagebox-send-message')).tap();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -69,9 +69,8 @@ describe('Ignore/Block User', () => {
|
|||
});
|
||||
describe('Ignore user from Message', () => {
|
||||
it('should ignore user from message', async () => {
|
||||
const channelName = data.channels.detoxpublicignore.name;
|
||||
const channelName = data.userRegularChannels.detoxpublic.name;
|
||||
await navigateToRoom(channelName);
|
||||
await element(by.id('room-view-join-button')).tap();
|
||||
await sleep(300);
|
||||
await sendMessage(data.users.alternate, channelName, 'message-01');
|
||||
await sendMessage(data.users.alternate, channelName, 'message-02');
|
||||
|
|
Loading…
Reference in New Issue