[NEW] Omnichannel Status Toggle (#2217)

Co-authored-by: Diego Mello <diegolmello@gmail.com>
This commit is contained in:
Djorkaeff Alexandre 2020-06-26 17:45:21 -03:00 committed by GitHub
parent 07e9bcb776
commit ff74f6ec9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 72 additions and 5 deletions

View File

@ -334,6 +334,7 @@ export default {
No_available_agents_to_transfer: 'No available agents to transfer', No_available_agents_to_transfer: 'No available agents to transfer',
Offline: 'Offline', Offline: 'Offline',
Oops: 'Oops!', Oops: 'Oops!',
Omnichannel: 'Omnichannel',
Onboarding_description: 'A workspace is your team or organizations space to collaborate. Ask the workspace admin for address to join or create one for your team.', Onboarding_description: 'A workspace is your team or organizations space to collaborate. Ask the workspace admin for address to join or create one for your team.',
Onboarding_join_workspace: 'Join a workspace', Onboarding_join_workspace: 'Join a workspace',
Onboarding_subtitle: 'Beyond Team Collaboration', Onboarding_subtitle: 'Beyond Team Collaboration',

View File

@ -14,6 +14,7 @@ import buildMessage from '../helpers/buildMessage';
import RocketChat from '../../rocketchat'; import RocketChat from '../../rocketchat';
import EventEmitter from '../../../utils/events'; import EventEmitter from '../../../utils/events';
import { removedRoom } from '../../../actions/room'; import { removedRoom } from '../../../actions/room';
import { setUser } from '../../../actions/login';
import { INAPP_NOTIFICATION_EMITTER } from '../../../containers/InAppNotification'; import { INAPP_NOTIFICATION_EMITTER } from '../../../containers/InAppNotification';
const removeListener = listener => listener.stop(); const removeListener = listener => listener.stop();
@ -241,6 +242,10 @@ export default function subscribeRooms() {
} }
const [type, data] = ddpMessage.fields.args; const [type, data] = ddpMessage.fields.args;
const [, ev] = ddpMessage.fields.eventName.split('/'); const [, ev] = ddpMessage.fields.eventName.split('/');
if (/userData/.test(ev)) {
const [{ diff }] = ddpMessage.fields.args;
store.dispatch(setUser({ statusLivechat: diff?.statusLivechat }));
}
if (/subscriptions/.test(ev)) { if (/subscriptions/.test(ev)) {
if (type === 'removed') { if (type === 'removed') {
try { try {

View File

@ -401,6 +401,7 @@ const RocketChat = {
status: result.me.status, status: result.me.status,
statusText: result.me.statusText, statusText: result.me.statusText,
customFields: result.me.customFields, customFields: result.me.customFields,
statusLivechat: result.me.statusLivechat,
emails: result.me.emails, emails: result.me.emails,
roles: result.me.roles roles: result.me.roles
}; };
@ -809,6 +810,10 @@ const RocketChat = {
// RC 2.2.0 // RC 2.2.0
return this.sdk.get('livechat/custom-fields'); return this.sdk.get('livechat/custom-fields');
}, },
changeLivechatStatus() {
// RC 0.26.0
return this.methodCall('livechat:changeLivechatStatus');
},
getUidDirectMessage(room) { getUidDirectMessage(room) {
const { id: userId } = reduxStore.getState().login.user; const { id: userId } = reduxStore.getState().login.user;

View File

@ -74,12 +74,12 @@ const handleDeleteRoom = function* handleDeleteRoom({ rid, t }) {
}; };
const handleCloseRoom = function* handleCloseRoom({ rid }) { const handleCloseRoom = function* handleCloseRoom({ rid }) {
const isMasterDetail = yield select(state => state.app.isMasterDetail);
const requestComment = yield select(state => state.settings.Livechat_request_comment_when_closing_conversation); const requestComment = yield select(state => state.settings.Livechat_request_comment_when_closing_conversation);
const closeRoom = async(comment = '') => { const closeRoom = async(comment = '') => {
try { try {
await RocketChat.closeLivechat(rid, comment); await RocketChat.closeLivechat(rid, comment);
const isMasterDetail = await select(state => state.app.isMasterDetail);
if (isMasterDetail) { if (isMasterDetail) {
Navigation.navigate('DrawerNavigator'); Navigation.navigate('DrawerNavigator');
} else { } else {

View File

@ -70,10 +70,20 @@ class SettingsView extends React.Component {
isMasterDetail: PropTypes.bool, isMasterDetail: PropTypes.bool,
logout: PropTypes.func.isRequired, logout: PropTypes.func.isRequired,
selectServerRequest: PropTypes.func, selectServerRequest: PropTypes.func,
token: PropTypes.string, user: PropTypes.shape({
roles: PropTypes.array,
statusLivechat: PropTypes.string
}),
appStart: PropTypes.func appStart: PropTypes.func
} }
get showLivechat() {
const { user } = this.props;
const { roles } = user;
return roles.includes('livechat-agent');
}
handleLogout = () => { handleLogout = () => {
showConfirmationAlert({ showConfirmationAlert({
message: I18n.t('You_will_be_logged_out_of_this_application'), message: I18n.t('You_will_be_logged_out_of_this_application'),
@ -114,6 +124,14 @@ class SettingsView extends React.Component {
} }
} }
toggleLivechat = async() => {
try {
await RocketChat.changeLivechatStatus();
} catch {
// Do nothing
}
}
navigateToScreen = (screen) => { navigateToScreen = (screen) => {
const { navigation } = this.props; const { navigation } = this.props;
navigation.navigate(screen); navigation.navigate(screen);
@ -172,6 +190,18 @@ class SettingsView extends React.Component {
); );
} }
renderLivechatSwitch = () => {
const { user } = this.props;
const { statusLivechat } = user;
return (
<Switch
value={statusLivechat === 'available'}
trackColor={SWITCH_TRACK_COLOR}
onValueChange={this.toggleLivechat}
/>
);
}
render() { render() {
const { server, isMasterDetail, theme } = this.props; const { server, isMasterDetail, theme } = this.props;
return ( return (
@ -292,6 +322,18 @@ class SettingsView extends React.Component {
<SectionSeparator theme={theme} /> <SectionSeparator theme={theme} />
{this.showLivechat ? (
<>
<ListItem
title={I18n.t('Omnichannel')}
testID='settings-view-livechat'
right={() => this.renderLivechatSwitch()}
theme={theme}
/>
<SectionSeparator theme={theme} />
</>
) : null}
<ListItem <ListItem
title={I18n.t('Send_crash_report')} title={I18n.t('Send_crash_report')}
testID='settings-view-crash-report' testID='settings-view-crash-report'
@ -331,7 +373,7 @@ class SettingsView extends React.Component {
const mapStateToProps = state => ({ const mapStateToProps = state => ({
server: state.server, server: state.server,
token: getUserSelector(state).token, user: getUserSelector(state),
allowCrashReport: state.crashReport.allowCrashReport, allowCrashReport: state.crashReport.allowCrashReport,
isMasterDetail: state.app.isMasterDetail isMasterDetail: state.app.isMasterDetail
}); });

View File

@ -81,7 +81,7 @@
"react-native-keyboard-tracking-view": "5.7.0", "react-native-keyboard-tracking-view": "5.7.0",
"react-native-keycommands": "2.0.3", "react-native-keycommands": "2.0.3",
"react-native-localize": "1.4.0", "react-native-localize": "1.4.0",
"react-native-mime-types": "^2.2.1", "react-native-mime-types": "2.3.0",
"react-native-modal": "11.5.6", "react-native-modal": "11.5.6",
"react-native-navigation-bar-color": "2.0.1", "react-native-navigation-bar-color": "2.0.1",
"react-native-notifications": "2.1.7", "react-native-notifications": "2.1.7",

View File

@ -81,3 +81,17 @@ index 17c2c2b..cb094e8 100644
/** Check result data for success, allowing override to ignore some errors */ /** Check result data for success, allowing override to ignore some errors */
success (result: any, ignore?: RegExp) { success (result: any, ignore?: RegExp) {
return ( return (
diff --git a/node_modules/@rocket.chat/sdk/lib/drivers/ddp.ts b/node_modules/@rocket.chat/sdk/lib/drivers/ddp.ts
index 247ce8b..2687abc 100644
--- a/node_modules/@rocket.chat/sdk/lib/drivers/ddp.ts
+++ b/node_modules/@rocket.chat/sdk/lib/drivers/ddp.ts
@@ -538,7 +538,8 @@ export class DDPDriver extends EventEmitter implements ISocket, IDriver {
'notification',
'rooms-changed',
'subscriptions-changed',
- 'uiInteraction'
+ 'uiInteraction',
+ 'userData'
].map(event => this.subscribe(topic, `${this.userId}/${event}`, false)))
}

View File

@ -11877,7 +11877,7 @@ react-native-localize@1.4.0:
resolved "https://registry.yarnpkg.com/react-native-localize/-/react-native-localize-1.4.0.tgz#4653596d066d0941c48f5404dc1c0d08b6950443" resolved "https://registry.yarnpkg.com/react-native-localize/-/react-native-localize-1.4.0.tgz#4653596d066d0941c48f5404dc1c0d08b6950443"
integrity sha512-W2MQxm6hzD549ZbZcbWzWtYJseY7S7WR2WgsNhm9ULmbwP7tXFfOTbkJjQoqgPXYSXogKN3srXhntVsNZL0Ksw== integrity sha512-W2MQxm6hzD549ZbZcbWzWtYJseY7S7WR2WgsNhm9ULmbwP7tXFfOTbkJjQoqgPXYSXogKN3srXhntVsNZL0Ksw==
react-native-mime-types@^2.2.1: react-native-mime-types@2.3.0:
version "2.3.0" version "2.3.0"
resolved "https://registry.yarnpkg.com/react-native-mime-types/-/react-native-mime-types-2.3.0.tgz#1278602c3da94ffb47c6400ef861901c4ebac420" resolved "https://registry.yarnpkg.com/react-native-mime-types/-/react-native-mime-types-2.3.0.tgz#1278602c3da94ffb47c6400ef861901c4ebac420"
integrity sha512-9l/kkT1QM0i0xAKkOADkP6jIMhqiS+R/eSKBS/lsUmuMYMqboClyrwTFFZwUcaVIN0SpeH4wOKhYTqCnFgRsEw== integrity sha512-9l/kkT1QM0i0xAKkOADkP6jIMhqiS+R/eSKBS/lsUmuMYMqboClyrwTFFZwUcaVIN0SpeH4wOKhYTqCnFgRsEw==