add: kebab and bottom sheet for omnichannel
This commit is contained in:
parent
99ea5d8e2a
commit
8d87401185
|
@ -243,6 +243,7 @@
|
||||||
"Forgot_password": "Forgot your password?",
|
"Forgot_password": "Forgot your password?",
|
||||||
"Forgot_Password": "Forgot Password",
|
"Forgot_Password": "Forgot Password",
|
||||||
"Forward": "Forward",
|
"Forward": "Forward",
|
||||||
|
"Forward_chat": "Forward chat",
|
||||||
"Forward_Chat": "Forward Chat",
|
"Forward_Chat": "Forward Chat",
|
||||||
"Forward_to_department": "Forward to department",
|
"Forward_to_department": "Forward to department",
|
||||||
"Forward_to_user": "Forward to user",
|
"Forward_to_user": "Forward to user",
|
||||||
|
@ -429,6 +430,7 @@
|
||||||
"resetting_password": "resetting password",
|
"resetting_password": "resetting password",
|
||||||
"RESET": "RESET",
|
"RESET": "RESET",
|
||||||
"Return": "Return",
|
"Return": "Return",
|
||||||
|
"Return_to_waiting_line": "Return to waiting line",
|
||||||
"Review_app_title": "Are you enjoying this app?",
|
"Review_app_title": "Are you enjoying this app?",
|
||||||
"Review_app_desc": "Give us 5 stars on {{store}}",
|
"Review_app_desc": "Give us 5 stars on {{store}}",
|
||||||
"Review_app_yes": "Sure!",
|
"Review_app_yes": "Sure!",
|
||||||
|
|
|
@ -193,6 +193,7 @@ export default {
|
||||||
ROOM_AUDIO_FINISH_F: 'room_audio_finish_f',
|
ROOM_AUDIO_FINISH_F: 'room_audio_finish_f',
|
||||||
ROOM_AUDIO_CANCEL: 'room_audio_cancel',
|
ROOM_AUDIO_CANCEL: 'room_audio_cancel',
|
||||||
ROOM_AUDIO_CANCEL_F: 'room_audio_cancel_f',
|
ROOM_AUDIO_CANCEL_F: 'room_audio_cancel_f',
|
||||||
|
ROOM_SHOW_MORE_ACTIONS: 'room_show_more_actions',
|
||||||
ROOM_SHOW_BOX_ACTIONS: 'room_show_box_actions',
|
ROOM_SHOW_BOX_ACTIONS: 'room_show_box_actions',
|
||||||
ROOM_BOX_ACTION_PHOTO: 'room_box_action_photo',
|
ROOM_BOX_ACTION_PHOTO: 'room_box_action_photo',
|
||||||
ROOM_BOX_ACTION_PHOTO_F: 'room_box_action_photo_f',
|
ROOM_BOX_ACTION_PHOTO_F: 'room_box_action_photo_f',
|
||||||
|
|
|
@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { dequal } from 'dequal';
|
import { dequal } from 'dequal';
|
||||||
import { Observable, Subscription } from 'rxjs';
|
import { Observable, Subscription } from 'rxjs';
|
||||||
|
import { Dispatch } from 'redux';
|
||||||
import { StackNavigationProp } from '@react-navigation/stack';
|
import { StackNavigationProp } from '@react-navigation/stack';
|
||||||
|
|
||||||
import * as HeaderButton from '../../containers/HeaderButton';
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
|
@ -11,18 +12,27 @@ import { events, logEvent } from '../../utils/log';
|
||||||
import { isTeamRoom } from '../../utils/room';
|
import { isTeamRoom } from '../../utils/room';
|
||||||
import { IApplicationState, SubscriptionType, TMessageModel, TSubscriptionModel } from '../../definitions';
|
import { IApplicationState, SubscriptionType, TMessageModel, TSubscriptionModel } from '../../definitions';
|
||||||
import { ChatsStackParamList } from '../../stacks/types';
|
import { ChatsStackParamList } from '../../stacks/types';
|
||||||
|
import { withActionSheet } from '../../containers/ActionSheet';
|
||||||
|
import i18n from '../../i18n';
|
||||||
|
import { showConfirmationAlert, showErrorAlert } from '../../utils/info';
|
||||||
|
import { closeRoom } from '../../actions/room';
|
||||||
|
import RocketChat from '../../lib/rocketchat';
|
||||||
|
|
||||||
interface IRightButtonsProps {
|
interface IRightButtonsProps {
|
||||||
userId?: string;
|
userId?: string;
|
||||||
threadsEnabled: boolean;
|
threadsEnabled: boolean;
|
||||||
rid?: string;
|
rid: string;
|
||||||
t: string;
|
t: string;
|
||||||
tmid?: string;
|
tmid?: string;
|
||||||
teamId?: string;
|
teamId?: string;
|
||||||
isMasterDetail: boolean;
|
isMasterDetail: boolean;
|
||||||
toggleFollowThread: Function;
|
toggleFollowThread: Function;
|
||||||
joined: boolean;
|
joined: boolean;
|
||||||
|
status?: string;
|
||||||
|
dispatch: Dispatch;
|
||||||
encrypted?: boolean;
|
encrypted?: boolean;
|
||||||
|
showActionSheet: Function; // TODO: Change to proper type
|
||||||
|
transferLivechatGuestPermission: boolean;
|
||||||
navigation: StackNavigationProp<ChatsStackParamList, 'RoomView'>;
|
navigation: StackNavigationProp<ChatsStackParamList, 'RoomView'>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +41,8 @@ interface IRigthButtonsState {
|
||||||
tunread: string[];
|
tunread: string[];
|
||||||
tunreadUser: string[];
|
tunreadUser: string[];
|
||||||
tunreadGroup: string[];
|
tunreadGroup: string[];
|
||||||
|
canReturnQueue: boolean;
|
||||||
|
canForwardGuest: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsState> {
|
class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsState> {
|
||||||
|
@ -43,12 +55,14 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
|
||||||
isFollowingThread: true,
|
isFollowingThread: true,
|
||||||
tunread: [],
|
tunread: [],
|
||||||
tunreadUser: [],
|
tunreadUser: [],
|
||||||
tunreadGroup: []
|
tunreadGroup: [],
|
||||||
|
canReturnQueue: false,
|
||||||
|
canForwardGuest: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const { tmid, rid } = this.props;
|
const { tmid, rid, t } = this.props;
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
if (tmid) {
|
if (tmid) {
|
||||||
try {
|
try {
|
||||||
|
@ -67,14 +81,32 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
|
||||||
console.log("Can't find subscription to observe.");
|
console.log("Can't find subscription to observe.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (t === 'l') {
|
||||||
|
const canReturnQueue = await this.canReturnQueue();
|
||||||
|
const canForwardGuest = await this.canForwardGuest();
|
||||||
|
this.setState({ canReturnQueue, canForwardGuest });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps: IRightButtonsProps) {
|
||||||
|
const { status } = this.props;
|
||||||
|
if (prevProps.status !== status) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps: IRightButtonsProps, nextState: IRigthButtonsState) {
|
shouldComponentUpdate(nextProps: IRightButtonsProps, nextState: IRigthButtonsState) {
|
||||||
const { isFollowingThread, tunread, tunreadUser, tunreadGroup } = this.state;
|
const { isFollowingThread, tunread, tunreadUser, tunreadGroup } = this.state;
|
||||||
const { teamId } = this.props;
|
const { teamId, status, joined } = this.props;
|
||||||
if (nextProps.teamId !== teamId) {
|
if (nextProps.teamId !== teamId) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (nextProps.status !== status) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (nextProps.joined !== joined) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (nextState.isFollowingThread !== isFollowingThread) {
|
if (nextState.isFollowingThread !== isFollowingThread) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -157,6 +189,69 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
canForwardGuest = async () => {
|
||||||
|
const { transferLivechatGuestPermission, rid } = this.props;
|
||||||
|
const permissions = await RocketChat.hasPermission([transferLivechatGuestPermission], rid);
|
||||||
|
return permissions[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
canReturnQueue = async () => {
|
||||||
|
try {
|
||||||
|
const { returnQueue } = await RocketChat.getRoutingConfig();
|
||||||
|
return returnQueue;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
returnLivechat = () => {
|
||||||
|
const { rid } = this.props;
|
||||||
|
showConfirmationAlert({
|
||||||
|
message: i18n.t('Would_you_like_to_return_the_inquiry'),
|
||||||
|
confirmationText: i18n.t('Yes'),
|
||||||
|
onPress: async () => {
|
||||||
|
try {
|
||||||
|
await RocketChat.returnLivechat(rid);
|
||||||
|
} catch (e: any) {
|
||||||
|
showErrorAlert(e.reason, i18n.t('Oops'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
closeLivechat = () => {
|
||||||
|
const { dispatch, rid } = this.props;
|
||||||
|
|
||||||
|
dispatch(closeRoom(rid));
|
||||||
|
};
|
||||||
|
|
||||||
|
showMoreActions = () => {
|
||||||
|
logEvent(events.ROOM_SHOW_MORE_ACTIONS);
|
||||||
|
const { showActionSheet, rid, navigation } = this.props;
|
||||||
|
const { canReturnQueue, canForwardGuest } = this.state;
|
||||||
|
|
||||||
|
const options = [
|
||||||
|
canForwardGuest && {
|
||||||
|
title: i18n.t('Forward_Chat'),
|
||||||
|
icon: 'chat-forward',
|
||||||
|
onPress: () => navigation.navigate('ForwardLivechatView', { rid })
|
||||||
|
},
|
||||||
|
canReturnQueue && {
|
||||||
|
title: i18n.t('Return_to_waiting_line'),
|
||||||
|
icon: 'move-to-the-queue',
|
||||||
|
onPress: () => this.returnLivechat()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18n.t('Close'),
|
||||||
|
icon: 'chat-close',
|
||||||
|
onPress: () => this.closeLivechat(),
|
||||||
|
danger: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
showActionSheet({ options });
|
||||||
|
};
|
||||||
|
|
||||||
goSearchView = () => {
|
goSearchView = () => {
|
||||||
logEvent(events.ROOM_GO_SEARCH);
|
logEvent(events.ROOM_GO_SEARCH);
|
||||||
const { rid, t, navigation, isMasterDetail, encrypted } = this.props;
|
const { rid, t, navigation, isMasterDetail, encrypted } = this.props;
|
||||||
|
@ -185,8 +280,17 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isFollowingThread, tunread, tunreadUser, tunreadGroup } = this.state;
|
const { isFollowingThread, tunread, tunreadUser, tunreadGroup } = this.state;
|
||||||
const { t, tmid, threadsEnabled, teamId, joined } = this.props;
|
const { t, tmid, threadsEnabled, teamId, joined, status } = this.props;
|
||||||
|
const isOmnichannelPreview = joined && status !== 'queued';
|
||||||
|
|
||||||
if (t === 'l') {
|
if (t === 'l') {
|
||||||
|
if (isOmnichannelPreview) {
|
||||||
|
return (
|
||||||
|
<HeaderButton.Container>
|
||||||
|
<HeaderButton.Item iconName='kebab' onPress={this.showMoreActions} testID='room-view-header-omnichannel-kebab' />
|
||||||
|
</HeaderButton.Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (tmid) {
|
if (tmid) {
|
||||||
|
@ -222,7 +326,8 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
|
||||||
const mapStateToProps = (state: IApplicationState) => ({
|
const mapStateToProps = (state: IApplicationState) => ({
|
||||||
userId: getUserSelector(state).id,
|
userId: getUserSelector(state).id,
|
||||||
threadsEnabled: state.settings.Threads_enabled as boolean,
|
threadsEnabled: state.settings.Threads_enabled as boolean,
|
||||||
isMasterDetail: state.app.isMasterDetail
|
isMasterDetail: state.app.isMasterDetail,
|
||||||
|
transferLivechatGuestPermission: state.permissions['transfer-livechat-guest']
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps)(RightButtonsContainer);
|
export default connect(mapStateToProps)(withActionSheet(RightButtonsContainer));
|
||||||
|
|
|
@ -115,7 +115,8 @@ const roomAttrsUpdate = [
|
||||||
'visitor',
|
'visitor',
|
||||||
'joinCodeRequired',
|
'joinCodeRequired',
|
||||||
'teamMain',
|
'teamMain',
|
||||||
'teamId'
|
'teamId',
|
||||||
|
'status'
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
interface IRoomViewProps extends IBaseScreen<ChatsStackParamList, 'RoomView'> {
|
interface IRoomViewProps extends IBaseScreen<ChatsStackParamList, 'RoomView'> {
|
||||||
|
@ -142,7 +143,9 @@ type TRoomUpdate = typeof roomAttrsUpdate[number];
|
||||||
interface IRoomViewState {
|
interface IRoomViewState {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
joined: boolean;
|
joined: boolean;
|
||||||
room: TSubscriptionModel | { rid: string; t: string; name?: string; fname?: string; prid?: string; joinCodeRequired?: boolean };
|
room:
|
||||||
|
| TSubscriptionModel
|
||||||
|
| { rid: string; t: string; name?: string; fname?: string; prid?: string; joinCodeRequired?: boolean; status?: boolean };
|
||||||
roomUpdate: {
|
roomUpdate: {
|
||||||
[K in TRoomUpdate]?: any; // TODO: get type from TSubscriptionModel
|
[K in TRoomUpdate]?: any; // TODO: get type from TSubscriptionModel
|
||||||
};
|
};
|
||||||
|
@ -512,6 +515,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
||||||
tmid={tmid}
|
tmid={tmid}
|
||||||
teamId={teamId}
|
teamId={teamId}
|
||||||
joined={joined}
|
joined={joined}
|
||||||
|
status={room.status}
|
||||||
t={this.t || t}
|
t={this.t || t}
|
||||||
encrypted={encrypted}
|
encrypted={encrypted}
|
||||||
navigation={navigation}
|
navigation={navigation}
|
||||||
|
|
Loading…
Reference in New Issue