Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions src/actionCreator.js

This file was deleted.

8 changes: 6 additions & 2 deletions src/events/doEventActionSideEffects.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
import { AppState } from 'react-native';
import type { GlobalState, GetState, Dispatch, Message } from '../types';
import type { EventAction } from '../actionTypes';
import { EVENT_NEW_MESSAGE } from '../actionConstants';
import { EVENT_NEW_MESSAGE, EVENT_TYPING_START } from '../actionConstants';
import { isHomeNarrow, isMessageInNarrow } from '../utils/narrow';
import { getActiveAccount, getChatScreenParams, getOwnEmail } from '../selectors';
import { playMessageSound } from '../utils/sound';
import { NULL_ARRAY } from '../nullObjects';
import { ensureTypingStatusExpiryLoop } from '../typing/typingActions';

/**
* React to incoming `MessageEvent`s.
Expand Down Expand Up @@ -43,7 +44,7 @@ const messageEvent = (state: GlobalState, message: Message): void => {
/**
* React to actions dispatched for Zulip server events.
*
* To be dispatched after the event actions are dispatched.
* To be dispatched before the event actions are dispatched.
*/
export default (action: EventAction) => async (dispatch: Dispatch, getState: GetState) => {
const state = getState();
Expand All @@ -52,6 +53,9 @@ export default (action: EventAction) => async (dispatch: Dispatch, getState: Get
messageEvent(state, action.message);
break;
}
case EVENT_TYPING_START:
dispatch(ensureTypingStatusExpiryLoop());
break;
default:
}
};
6 changes: 2 additions & 4 deletions src/events/eventActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { deadQueue } from '../session/sessionActions';
import eventToAction from './eventToAction';
import doEventActionSideEffects from './doEventActionSideEffects';
import { tryGetAuth } from '../selectors';
import actionCreator from '../actionCreator';
import { BackoffMachine } from '../utils/async';
import { ApiError } from '../api/apiErrors';

Expand Down Expand Up @@ -73,16 +72,15 @@ export const startEventPolling = (queueId: number, eventId: number) => async (

const actions = eventsToActions(getState(), events);

actionCreator(dispatch, actions, getState());
dispatchOrBatch(dispatch, actions);

actions.forEach(action => {
// These side effects should not be moved to reducers, which
// are explicitly not the place for side effects (see
// https://redux.js.org/faq/actions).
dispatch(doEventActionSideEffects(action));
});

dispatchOrBatch(dispatch, actions);

lastEventId = Math.max.apply(null, [lastEventId, ...events.map(x => x.id)]);
} catch (e) {
if (e.httpStatus === 401) {
Expand Down
26 changes: 0 additions & 26 deletions src/typing/clearTypingNotification.js

This file was deleted.

36 changes: 35 additions & 1 deletion src/typing/typingActions.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,41 @@
/* @flow strict-local */
import type { Action } from '../types';
import type { Action, Dispatch, GetState } from '../types';

import { sleep } from '../utils/async';
import { getTyping } from '../directSelectors';

export const clearTyping = (outdatedNotifications: string[]): Action => ({
type: 'CLEAR_TYPING',
outdatedNotifications,
});

const typingStatusExpiryLoop = () => async (dispatch: Dispatch, getState: GetState) => {
// loop to auto dismiss typing notifications after typingNotificationTimeout
// eslint-disable-next-line no-constant-condition
while (true) {
await sleep(15000);
const currentTime = new Date().getTime();
const typing = getTyping(getState());
if (Object.keys(typing).length === 0) {
break; // break if no typing notifications
}
const outdatedNotifications = [];
Object.keys(typing).forEach(recipients => {
if (currentTime - typing[recipients].time >= 15000) {
outdatedNotifications.push(recipients);
}
});
dispatch(clearTyping(outdatedNotifications));
}
};

/** Start the typing-status expiry loop, if there isn't one already. */
export const ensureTypingStatusExpiryLoop = () => async (
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me, this line-break change suggests that you're also affected by the auto-formatting issue I mentioned here, hmm. IIUC this should have been done in the "ensureTypingStatusExpiryLoop" rename commit.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah indeed, thanks. Pushed a fix.

dispatch: Dispatch,
getState: GetState,
) => {
const state = getState();
if (Object.keys(state.typing).length === 0) {
dispatch(typingStatusExpiryLoop());
}
};