Skip to content

Commit

Permalink
[IMPROVE] Add ignore user to user profile (#4600)
Browse files Browse the repository at this point in the history
* button ignore and pased the param

* load room from database and check is is ignored

* move handleIgnore to lib/method/helpers

* Ignore and Unignore, also reactivity

* block and unblock user

* pass fromRid from actionView to InfoView too

* remove console.log

* unsubscribe subscriptionFrom

* block and unblock user from dm

* test to block user and ignore user

* minor tweak

* tweak data

* minor tweak

* add test before tapBack

* refactor names
  • Loading branch information
reinaldonetof authored and diegolmello committed Oct 17, 2022
1 parent 331a202 commit 7fdf2dc
Show file tree
Hide file tree
Showing 10 changed files with 220 additions and 38 deletions.
19 changes: 19 additions & 0 deletions app/lib/methods/helpers/handleIgnore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { LISTENER } from '../../../containers/Toast';
import I18n from '../../../i18n';
import EventEmitter from './events';
import log from './log';
import { Services } from '../../services';

export const handleIgnore = async (userId: string, ignore: boolean, rid: string) => {
try {
await Services.ignoreUser({
rid,
userId,
ignore
});
const message = I18n.t(ignore ? 'User_has_been_ignored' : 'User_has_been_unignored');
EventEmitter.emit(LISTENER, { message });
} catch (e) {
log(e);
}
};
1 change: 1 addition & 0 deletions app/lib/methods/helpers/log/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ export default {
RI_GO_RI_EDIT: 'ri_go_ri_edit',
RI_GO_LIVECHAT_EDIT: 'ri_go_livechat_edit',
RI_GO_ROOM_USER: 'ri_go_room_user',
RI_TOGGLE_BLOCK_USER: 'ri_toggle_block_user',

// ROOM INFO EDIT VIEW
RI_EDIT_TOGGLE_ROOM_TYPE: 'ri_edit_toggle_room_type',
Expand Down
1 change: 1 addition & 0 deletions app/stacks/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export type ChatsStackParamList = {
rid: string;
t: SubscriptionType;
showCloseModal?: boolean;
fromRid?: string;
};
RoomInfoEditView: {
rid: string;
Expand Down
3 changes: 2 additions & 1 deletion app/views/RoomActionsView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,8 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
rid,
t,
room,
member
member,
fromRid: room.rid
}
})
}
Expand Down
107 changes: 86 additions & 21 deletions app/views/RoomInfoView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import { ILivechatVisitor } from '../../definitions/ILivechatVisitor';
import { callJitsi } from '../../lib/methods';
import { getRoomTitle, getUidDirectMessage, hasPermission } from '../../lib/methods/helpers';
import { Services } from '../../lib/services';
import { getSubscriptionByRoomId } from '../../lib/database/services/Subscription';
import { handleIgnore } from '../../lib/methods/helpers/handleIgnore';

interface IGetRoomTitle {
room: ISubscription;
Expand Down Expand Up @@ -108,6 +110,7 @@ interface IRoomInfoViewState {
room: ISubscription;
roomUser: IUserParsed | ILivechatVisitorModified;
showEdit: boolean;
roomFromRid?: TSubscriptionModel;
}

class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewState> {
Expand All @@ -121,22 +124,29 @@ class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewStat

private roomObservable?: Observable<TSubscriptionModel>;

private fromRid?: string;

private subscriptionRoomFromRid?: Subscription;

constructor(props: IRoomInfoViewProps) {
super(props);
const room = props.route.params?.room;
const roomUser = props.route.params?.member;
this.rid = props.route.params?.rid;
this.t = props.route.params?.t;
this.fromRid = props.route.params?.fromRid;
this.state = {
room: (room || { rid: this.rid, t: this.t }) as any,
roomUser: roomUser || {},
showEdit: false
showEdit: false,
roomFromRid: undefined
};
}

componentDidMount() {
if (this.isDirect) {
this.loadUser();
this.loadRoomFromRid();
} else {
this.loadRoom();
}
Expand All @@ -154,6 +164,9 @@ class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewStat
if (this.subscription && this.subscription.unsubscribe) {
this.subscription.unsubscribe();
}
if (this.subscriptionRoomFromRid && this.subscriptionRoomFromRid.unsubscribe) {
this.subscriptionRoomFromRid.unsubscribe();
}
if (this.unsubscribeFocus) {
this.unsubscribeFocus();
}
Expand Down Expand Up @@ -266,6 +279,19 @@ class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewStat
}
};

loadRoomFromRid = async () => {
if (this.fromRid) {
try {
const sub = await getSubscriptionByRoomId(this.fromRid);
this.subscriptionRoomFromRid = sub?.observe().subscribe(roomFromRid => {
this.setState({ roomFromRid });
});
} catch (e) {
// do nothing
}
}
};

loadRoom = async () => {
const { room: roomState } = this.state;
const { route, editRoomPermission, editOmnichannelContact, editLivechatRoomCustomfields } = this.props;
Expand Down Expand Up @@ -351,11 +377,32 @@ class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewStat
}
};

handleCreateDirectMessage = async (onPress: () => void) => {
try {
if (this.isDirect) {
await this.createDirect();
}
onPress();
} catch {
EventEmitter.emit(LISTENER, {
message: I18n.t('error-action-not-allowed', { action: I18n.t('Create_Direct_Messages') })
});
}
};

videoCall = () => {
const { room } = this.state;
callJitsi(room);
};

handleBlockUser = async (rid: string, blocked: string, block: boolean) => {
logEvent(events.RI_TOGGLE_BLOCK_USER);
try {
await Services.toggleBlockUser(rid, blocked, block);
} catch (e) {
log(e);
}
};
renderAvatar = (room: ISubscription, roomUser: IUserParsed) => {
const { theme } = this.props;

Expand All @@ -370,36 +417,54 @@ class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewStat
);
};

renderButton = (onPress: () => void, iconName: TIconsName, text: string) => {
renderButton = (onPress: () => void, iconName: TIconsName, text: string, danger?: boolean) => {
const { theme } = this.props;

const onActionPress = async () => {
try {
if (this.isDirect) {
await this.createDirect();
}
onPress();
} catch {
EventEmitter.emit(LISTENER, {
message: I18n.t('error-action-not-allowed', { action: I18n.t('Create_Direct_Messages') })
});
}
};

const color = danger ? themes[theme].dangerColor : themes[theme].actionTintColor;
return (
<BorderlessButton onPress={onActionPress} style={styles.roomButton}>
<CustomIcon name={iconName} size={30} color={themes[theme].actionTintColor} />
<Text style={[styles.roomButtonText, { color: themes[theme].actionTintColor }]}>{text}</Text>
<BorderlessButton testID={`room-info-view-${iconName}`} onPress={onPress} style={styles.roomButton}>
<CustomIcon name={iconName} size={30} color={color} />
<Text style={[styles.roomButtonText, { color }]}>{text}</Text>
</BorderlessButton>
);
};

renderButtons = () => {
const { roomFromRid, roomUser } = this.state;
const { jitsiEnabled } = this.props;

const isFromDm = roomFromRid?.rid ? new RegExp(roomUser._id).test(roomFromRid.rid) : false;
const isDirectFromSaved = this.isDirect && this.fromRid && roomFromRid;

// Following the web behavior, when is a DM with myself, shouldn't appear block or ignore option
const isDmWithMyself = roomFromRid?.uids && roomFromRid.uids?.filter(uid => uid !== roomUser._id).length === 0;

const ignored = roomFromRid?.ignored;
const isIgnored = ignored?.includes?.(roomUser._id);

const blocker = roomFromRid?.blocker;

return (
<View style={styles.roomButtonsContainer}>
{this.renderButton(this.goRoom, 'message', I18n.t('Message'))}
{jitsiEnabled && this.isDirect ? this.renderButton(this.videoCall, 'camera', I18n.t('Video_call')) : null}
{this.renderButton(() => this.handleCreateDirectMessage(this.goRoom), 'message', I18n.t('Message'))}
{jitsiEnabled && this.isDirect
? this.renderButton(() => this.handleCreateDirectMessage(this.videoCall), 'camera', I18n.t('Video_call'))
: null}
{isDirectFromSaved && !isFromDm && !isDmWithMyself
? this.renderButton(
() => handleIgnore(roomUser._id, !isIgnored, roomFromRid.rid),
'ignore',
I18n.t(isIgnored ? 'Unignore' : 'Ignore'),
true
)
: null}
{isDirectFromSaved && isFromDm
? this.renderButton(
() => this.handleBlockUser(roomFromRid.rid, roomUser._id, !blocker),
'ignore',
I18n.t(`${blocker ? 'Unblock' : 'Block'}_user`),
true
)
: null}
</View>
);
};
Expand Down
14 changes: 0 additions & 14 deletions app/views/RoomMembersView/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,20 +217,6 @@ export const handleRemoveUserFromRoom = async (
}
};

export const handleIgnore = async (selectedUser: TUserModel, ignore: boolean, rid: string) => {
try {
await Services.ignoreUser({
rid,
userId: selectedUser._id,
ignore
});
const message = I18n.t(ignore ? 'User_has_been_ignored' : 'User_has_been_unignored');
EventEmitter.emit(LISTENER, { message });
} catch (e) {
log(e);
}
};

export const handleOwner = async (
selectedUser: TUserModel,
isOwner: boolean,
Expand Down
4 changes: 2 additions & 2 deletions app/views/RoomMembersView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { TSubscriptionModel, TUserModel } from '../../definitions';
import I18n from '../../i18n';
import { useAppSelector, usePermissions } from '../../lib/hooks';
import { getRoomTitle, isGroupChat } from '../../lib/methods/helpers';
import { handleIgnore } from '../../lib/methods/helpers/handleIgnore';
import { showConfirmationAlert } from '../../lib/methods/helpers/info';
import log from '../../lib/methods/helpers/log';
import scrollPersistTaps from '../../lib/methods/helpers/scrollPersistTaps';
Expand All @@ -28,7 +29,6 @@ import ActionsSection from './components/ActionsSection';
import {
fetchRole,
fetchRoomMembersRoles,
handleIgnore,
handleLeader,
handleModerator,
handleMute,
Expand Down Expand Up @@ -207,7 +207,7 @@ const RoomMembersView = (): React.ReactElement => {
options.push({
icon: 'ignore',
title: I18n.t(isIgnored ? 'Unignore' : 'Ignore'),
onPress: () => handleIgnore(selectedUser, !isIgnored, room.rid),
onPress: () => handleIgnore(selectedUser._id, !isIgnored, room.rid),
testID: 'action-sheet-ignore-user'
});
}
Expand Down
3 changes: 3 additions & 0 deletions app/views/RoomView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1109,10 +1109,13 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {

navToRoomInfo = (navParam: any) => {
const { navigation, user, isMasterDetail } = this.props;
const { room } = this.state;

logEvent(events[`ROOM_GO_${navParam.t === 'd' ? 'USER' : 'ROOM'}_INFO`]);
if (navParam.rid === user.id) {
return;
}
navParam.fromRid = room.rid;
if (isMasterDetail) {
navParam.showCloseModal = true;
// @ts-ignore
Expand Down
3 changes: 3 additions & 0 deletions e2e/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ const data = {
detoxpublicprotected: {
name: 'detox-public-protected',
joinCode: '123'
},
detoxpublicignore: {
name: `detox-public-ignore-${value}`
}
},
groups: {
Expand Down
Loading

0 comments on commit 7fdf2dc

Please sign in to comment.