[FIX] Unread not going away when receiving a message from inside a room (#194)

* Fix Unread inside Room
This commit is contained in:
Martin Schoeler 2018-01-15 16:44:20 -02:00 committed by Guilherme Gazzo
parent a0cfe3b8c3
commit ec1782e504
8 changed files with 88 additions and 20 deletions

View File

@ -28,7 +28,7 @@ export const FORGOT_PASSWORD = createRequestTypes('FORGOT_PASSWORD', [
]);
export const USER = createRequestTypes('USER', ['SET']);
export const ROOMS = createRequestTypes('ROOMS', [...defaultTypes, 'SET_SEARCH']);
export const ROOM = createRequestTypes('ROOM', ['ADD_USER_TYPING', 'REMOVE_USER_TYPING', 'SOMEONE_TYPING', 'OPEN', 'USER_TYPING']);
export const ROOM = createRequestTypes('ROOM', ['ADD_USER_TYPING', 'REMOVE_USER_TYPING', 'SOMEONE_TYPING', 'OPEN', 'CLOSE', 'USER_TYPING', 'MESSAGE_RECEIVED', 'SET_LAST_OPEN']);
export const APP = createRequestTypes('APP', ['READY', 'INIT']);
export const MESSAGES = createRequestTypes('MESSAGES', [
...defaultTypes,

View File

@ -29,9 +29,29 @@ export function openRoom(room) {
};
}
export function closeRoom() {
return {
type: types.ROOM.CLOSE
};
}
export function userTyping(status = true) {
return {
type: types.ROOM.USER_TYPING,
status
};
}
export function roomMessageReceived(message) {
return {
type: types.ROOM.MESSAGE_RECEIVED,
message
};
}
export function setLastOpen(date = new Date()) {
return {
type: types.ROOM.SET_LAST_OPEN,
date
};
}

View File

@ -114,13 +114,14 @@ export default class Socket extends EventEmitter {
subscribe(name, ...params) {
return this.send({
msg: 'sub', name, params
}).then((data) => {
this.subscriptions[data.id] = {
}).then((id) => {
const args = {
name,
params,
unsubscribe: () => this.unsubscribe(data.id)
unsubscribe: () => this.unsubscribe(id)
};
return this.subscriptions[data.id];
this.subscriptions[id] = args;
return args;
});
}
}

View File

@ -8,7 +8,7 @@ import settingsType from '../constants/settings';
import messagesStatus from '../constants/messagesStatus';
import database from './realm';
import * as actions from '../actions';
import { someoneTyping } from '../actions/room';
import { someoneTyping, roomMessageReceived } from '../actions/room';
import { setUser } from '../actions/login';
import { disconnect, disconnect_by_user, connectSuccess, connectFailure } from '../actions/connect';
import { requestActiveUser } from '../actions/activeUsers';
@ -98,10 +98,10 @@ const RocketChat = {
}
});
this.ddp.on('stream-room-messages', ddpMessage => database.write(() => {
this.ddp.on('stream-room-messages', (ddpMessage) => {
const message = this._buildMessage(ddpMessage.fields.args[0]);
database.create('messages', message, true);
}));
return reduxStore.dispatch(roomMessageReceived(message));
});
this.ddp.on('stream-notify-room', (ddpMessage) => {
const [_rid, ev] = ddpMessage.fields.eventName.split('/');

View File

@ -9,7 +9,17 @@ export default function room(state = initialState, action) {
case types.ROOM.OPEN:
return {
...initialState,
...action.room
...action.room,
lastOpen: new Date()
};
case types.ROOM.CLOSE:
return {
...initialState
};
case types.ROOM.SET_LAST_OPEN:
return {
...state,
lastOpen: action.date
};
case types.ROOM.ADD_USER_TYPING:
return {

View File

@ -1,11 +1,12 @@
import { put, call, takeLatest, take, select, race, fork, cancel } from 'redux-saga/effects';
import { put, call, takeLatest, take, select, race, fork, cancel, takeEvery } from 'redux-saga/effects';
import { delay } from 'redux-saga';
import { FOREGROUND } from 'redux-enhancer-react-native-appstate';
import { FOREGROUND, BACKGROUND } from 'redux-enhancer-react-native-appstate';
import * as types from '../actions/actionsTypes';
import { roomsSuccess, roomsFailure } from '../actions/rooms';
import { addUserTyping, removeUserTyping } from '../actions/room';
import { addUserTyping, removeUserTyping, setLastOpen } from '../actions/room';
import { messagesRequest } from '../actions/messages';
import RocketChat from '../lib/rocketchat';
import database from '../lib/realm';
const getRooms = function* getRooms() {
return yield RocketChat.getRooms();
@ -43,6 +44,17 @@ const usersTyping = function* usersTyping({ rid }) {
}
}
};
const handleMessageReceived = function* handleMessageReceived({ message }) {
const room = yield select(state => state.room);
if (message.rid === room.rid) {
database.write(() => {
database.create('messages', message, true);
});
RocketChat.readMessages(room.rid);
}
};
const watchRoomOpen = function* watchRoomOpen({ room }) {
const auth = yield select(state => state.login.isAuthenticated);
@ -50,7 +62,7 @@ const watchRoomOpen = function* watchRoomOpen({ room }) {
yield take(types.LOGIN.SUCCESS);
}
const subscriptions = [];
yield put(messagesRequest({ rid: room.rid }));
const { open } = yield race({
@ -62,12 +74,16 @@ const watchRoomOpen = function* watchRoomOpen({ room }) {
return;
}
RocketChat.readMessages(room.rid);
subscriptions.push(RocketChat.subscribe('stream-room-messages', room.rid, false));
subscriptions.push(RocketChat.subscribe('stream-notify-room', `${ room.rid }/typing`, false));
const subscriptions = yield Promise.all([RocketChat.subscribe('stream-room-messages', room.rid, false), RocketChat.subscribe('stream-notify-room', `${ room.rid }/typing`, false)]);
const thread = yield fork(usersTyping, { rid: room.rid });
yield take(types.ROOM.OPEN);
yield race({
open: take(types.ROOM.OPEN),
close: take(types.ROOM.CLOSE)
});
cancel(thread);
subscriptions.forEach(sub => sub.unsubscribe());
subscriptions.forEach((sub) => {
sub.unsubscribe().catch(e => alert(e));
});
};
const watchuserTyping = function* watchuserTyping({ status }) {
@ -96,11 +112,18 @@ const updateRoom = function* updateRoom() {
}
yield put(messagesRequest({ rid: room.rid }));
};
const updateLastOpen = function* updateLastOpen() {
yield put(setLastOpen());
};
const root = function* root() {
yield takeLatest(types.ROOM.USER_TYPING, watchuserTyping);
yield takeLatest(types.LOGIN.SUCCESS, watchRoomsRequest);
yield takeLatest(types.ROOM.OPEN, watchRoomOpen);
yield takeEvery(types.ROOM.MESSAGE_RECEIVED, handleMessageReceived);
yield takeLatest(FOREGROUND, updateRoom);
yield takeLatest(FOREGROUND, watchRoomsRequest);
yield takeLatest(BACKGROUND, updateLastOpen);
};
export default root;

View File

@ -9,14 +9,18 @@ import realm from '../../../lib/realm';
import Avatar from '../../../containers/Avatar';
import { STATUS_COLORS } from '../../../constants/colors';
import styles from './styles';
import { closeRoom } from '../../../actions/room';
@connect(state => ({
user: state.login.user,
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '',
activeUsers: state.activeUsers
}), dispatch => ({
close: () => dispatch(closeRoom())
}))
export default class extends React.PureComponent {
static propTypes = {
close: PropTypes.func.isRequired,
navigation: PropTypes.object.isRequired,
user: PropTypes.object.isRequired,
baseUrl: PropTypes.string,
@ -57,7 +61,15 @@ export default class extends React.PureComponent {
isDirect = () => this.state.room && this.state.room.t === 'd';
renderLeft = () => <HeaderBackButton onPress={() => this.props.navigation.goBack(null)} tintColor='#292E35' title='Back' titleStyle={{ display: 'none' }} />;
renderLeft = () => (<HeaderBackButton
onPress={() => {
this.props.close();
this.props.navigation.goBack(null);
}}
tintColor='#292E35'
title='Back'
titleStyle={{ display: 'none' }}
/>);
renderTitle() {
if (!this.state.roomName) {

View File

@ -32,7 +32,8 @@ const typing = () => <Typing />;
Site_Url: state.settings.Site_Url || state.server ? state.server.server : '',
Message_TimeFormat: state.settings.Message_TimeFormat,
loading: state.messages.isFetching,
user: state.login.user
user: state.login.user,
lastOpened: state.room.lastOpen
}),
dispatch => ({
actions: bindActionCreators(actions, dispatch),
@ -42,6 +43,7 @@ const typing = () => <Typing />;
)
export default class RoomView extends React.Component {
static propTypes = {
// lastOpened: PropTypes.instanceOf(Date),
navigation: PropTypes.object.isRequired,
openRoom: PropTypes.func.isRequired,
user: PropTypes.object.isRequired,