175 lines
5.2 KiB
JavaScript
175 lines
5.2 KiB
JavaScript
import { Alert } from 'react-native';
|
|
import { delay, put, race, select, take, takeLatest, actionChannel, throttle, fork, cancel } from 'redux-saga/effects';
|
|
|
|
import EventEmitter from '../lib/methods/helpers/events';
|
|
import Navigation from '../lib/navigation/appNavigation';
|
|
import * as types from '../actions/actionsTypes';
|
|
import { removedRoom } from '../actions/room';
|
|
import log, { events, logEvent } from '../lib/methods/helpers/log';
|
|
import I18n from '../i18n';
|
|
import { showErrorAlert } from '../lib/methods/helpers/info';
|
|
import { LISTENER } from '../containers/Toast';
|
|
import { Services } from '../lib/services';
|
|
import getMoreMessages from '../lib/methods/getMoreMessages';
|
|
import { getMessageById } from '../lib/database/services/Message';
|
|
|
|
function* watchHistoryRequests() {
|
|
const requestChan = yield actionChannel(types.ROOM.HISTORY_REQUEST);
|
|
while (true) {
|
|
const { rid, t, tmid, loaderId } = yield take(requestChan);
|
|
|
|
const loaderItem = yield getMessageById(loaderId);
|
|
if (loaderItem) {
|
|
try {
|
|
yield getMoreMessages({ rid, t, tmid, loaderItem });
|
|
} catch (e) {
|
|
log(e);
|
|
} finally {
|
|
yield put({ type: types.ROOM.HISTORY_FINISHED, loaderId });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let inactiveTypingTask = null;
|
|
|
|
const clearUserTyping = function* clearUserTyping({ rid, status }) {
|
|
try {
|
|
if (!status) {
|
|
yield Services.emitTyping(rid, false);
|
|
if (inactiveTypingTask) {
|
|
yield cancel(inactiveTypingTask);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
log(e);
|
|
}
|
|
};
|
|
|
|
const clearInactiveTyping = function* clearInactiveTyping({ rid }) {
|
|
yield delay(5000);
|
|
yield clearUserTyping({ rid, status: false });
|
|
};
|
|
|
|
const watchUserTyping = function* watchUserTyping({ rid, status }) {
|
|
try {
|
|
if (status) {
|
|
yield Services.emitTyping(rid, status);
|
|
if (inactiveTypingTask) {
|
|
yield cancel(inactiveTypingTask);
|
|
}
|
|
inactiveTypingTask = yield fork(clearInactiveTyping, { rid });
|
|
}
|
|
} catch (e) {
|
|
log(e);
|
|
}
|
|
};
|
|
|
|
const handleRemovedRoom = function* handleRemovedRoom(roomType, actionType) {
|
|
const isMasterDetail = yield select(state => state.app.isMasterDetail);
|
|
if (isMasterDetail) {
|
|
yield Navigation.navigate('DrawerNavigator');
|
|
} else {
|
|
yield Navigation.navigate('RoomsListView');
|
|
}
|
|
|
|
if (actionType === 'leave') {
|
|
EventEmitter.emit(LISTENER, {
|
|
message: roomType === 'team' ? I18n.t('Left_The_Team_Successfully') : I18n.t('Left_The_Room_Successfully')
|
|
});
|
|
}
|
|
if (actionType === 'delete') {
|
|
EventEmitter.emit(LISTENER, {
|
|
message: roomType === 'team' ? I18n.t('Deleted_The_Team_Successfully') : I18n.t('Deleted_The_Room_Successfully')
|
|
});
|
|
}
|
|
|
|
// types.ROOM.REMOVE is triggered by `subscriptions-changed` with `removed` arg
|
|
const { timeout } = yield race({
|
|
deleteFinished: take(types.ROOM.REMOVED),
|
|
timeout: delay(3000)
|
|
});
|
|
if (timeout) {
|
|
put(removedRoom());
|
|
}
|
|
};
|
|
|
|
const handleLeaveRoom = function* handleLeaveRoom({ room, roomType, selected }) {
|
|
logEvent(events.RA_LEAVE);
|
|
try {
|
|
let result = {};
|
|
|
|
if (roomType === 'channel') {
|
|
result = yield Services.leaveRoom(room.rid, room.t);
|
|
} else if (roomType === 'team') {
|
|
result = yield Services.leaveTeam({ teamId: room.teamId, ...(selected && { rooms: selected }) });
|
|
}
|
|
|
|
if (result?.success) {
|
|
yield handleRemovedRoom(roomType, 'leave');
|
|
}
|
|
} catch (e) {
|
|
logEvent(events.RA_LEAVE_F);
|
|
if (e.data && e.data.errorType === 'error-you-are-last-owner') {
|
|
Alert.alert(I18n.t('Oops'), I18n.t(e.data.errorType));
|
|
} else if (e?.data?.error === 'last-owner-can-not-be-removed') {
|
|
Alert.alert(I18n.t('Oops'), I18n.t(e.data.error));
|
|
} else {
|
|
Alert.alert(I18n.t('Oops'), I18n.t('There_was_an_error_while_action', { action: I18n.t('leaving_room') }));
|
|
}
|
|
}
|
|
};
|
|
|
|
const handleDeleteRoom = function* handleDeleteRoom({ room, roomType, selected }) {
|
|
logEvent(events.RI_EDIT_DELETE);
|
|
try {
|
|
let result = {};
|
|
|
|
if (roomType === 'channel') {
|
|
result = yield Services.deleteRoom(room.rid || room._id, room.t);
|
|
} else if (roomType === 'team') {
|
|
result = yield Services.deleteTeam({ teamId: room.teamId, ...(selected && { roomsToRemove: selected }) });
|
|
}
|
|
|
|
if (result?.success) {
|
|
yield handleRemovedRoom(roomType, 'delete');
|
|
}
|
|
} catch (e) {
|
|
logEvent(events.RI_EDIT_DELETE_F);
|
|
Alert.alert(
|
|
I18n.t('Oops'),
|
|
I18n.t('There_was_an_error_while_action', {
|
|
action: roomType === 'team' ? I18n.t('deleting_team') : I18n.t('deleting_room')
|
|
})
|
|
);
|
|
}
|
|
};
|
|
|
|
const handleForwardRoom = function* handleForwardRoom({ transferData }) {
|
|
try {
|
|
const result = yield Services.forwardLivechat(transferData);
|
|
if (result === true) {
|
|
const isMasterDetail = yield select(state => state.app.isMasterDetail);
|
|
if (isMasterDetail) {
|
|
Navigation.navigate('DrawerNavigator');
|
|
} else {
|
|
Navigation.navigate('RoomsListView');
|
|
}
|
|
} else {
|
|
showErrorAlert(I18n.t('No_available_agents_to_transfer'), I18n.t('Oops'));
|
|
}
|
|
} catch (e) {
|
|
showErrorAlert(e.reason, I18n.t('Oops'));
|
|
}
|
|
};
|
|
|
|
const root = function* root() {
|
|
yield takeLatest(types.ROOM.USER_TYPING, clearUserTyping);
|
|
yield throttle(3000, types.ROOM.USER_TYPING, watchUserTyping);
|
|
yield takeLatest(types.ROOM.LEAVE, handleLeaveRoom);
|
|
yield takeLatest(types.ROOM.DELETE, handleDeleteRoom);
|
|
yield takeLatest(types.ROOM.FORWARD, handleForwardRoom);
|
|
yield watchHistoryRequests();
|
|
};
|
|
export default root;
|