Skip to content

Commit

Permalink
Enhance DMActivityHandler
Browse files Browse the repository at this point in the history
Summary: This differential addresses Ashoat review for this diff: https://phab.comm.dev/D13246

Test Plan:
1. Create thick thread between users A and B.
2. Log in as user A on two devices (on web and on native) and log in as user B on third device.
3. Send message from B to A. Open the thread as A on web. Ensure rescinding happens on native.
4. Open the thread as A on native. Change opened thread as A on web. Send messages from B to A. Ensure that thread remains read on web.

Reviewers: tomek, kamil, ashoat

Reviewed By: ashoat

Differential Revision: https://phab.comm.dev/D13305
  • Loading branch information
marcinwasowicz committed Sep 12, 2024
1 parent 0f616c5 commit 7c7da1b
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 53 deletions.
11 changes: 3 additions & 8 deletions lib/handlers/dm-activity-handler.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
// @flow

import invariant from 'invariant';
import * as React from 'react';

import { updateActivityActionTypes } from '../actions/activity-actions.js';
import {
type OutboundDMOperationSpecification,
dmOperationSpecificationTypes,
} from '../shared/dm-ops/dm-op-utils.js';
import { useProcessAndSendDMOperation } from '../shared/dm-ops/process-dm-ops.js';
import { getMostRecentNonLocalMessageID } from '../shared/message-utils.js';
import { threadIsPending } from '../shared/thread-utils.js';
import type { ActivityUpdateSuccessPayload } from '../types/activity-types.js';
import type { DMChangeThreadReadStatusOperation } from '../types/dm-ops.js';
import type { RawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
import { threadTypeIsThick } from '../types/thread-types-enum.js';
Expand All @@ -20,7 +19,7 @@ import { useSelector } from '../utils/redux-utils.js';
function useUpdateDMActivity(): (
viewerID: string,
activeThreadInfo: RawThreadInfo,
) => Promise<ActivityUpdateSuccessPayload> {
) => Promise<void> {
const processAndSendDMOperation = useProcessAndSendDMOperation();
return React.useCallback(
async (viewerID: string, activeThreadInfo: RawThreadInfo) => {
Expand All @@ -43,7 +42,6 @@ function useUpdateDMActivity(): (
};

await processAndSendDMOperation(opSpecification);
return { activityUpdates: {}, result: { unfocusedToUnread: [] } };
},
[processAndSendDMOperation],
);
Expand Down Expand Up @@ -89,10 +87,7 @@ function useDMActivityHandler(activeThread: ?string): void {
return;
}

void dispatchActionPromise(
updateActivityActionTypes,
updateDMActivity(viewerID, activeThreadInfo),
);
void updateDMActivity(viewerID, activeThreadInfo);
}, [
updateDMActivity,
dispatchActionPromise,
Expand Down
18 changes: 3 additions & 15 deletions native/components/dm-activity-handler.react.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
// @flow

import * as React from 'react';

import useDMActivityHandler from 'lib/handlers/dm-activity-handler.js';
import { isLoggedIn } from 'lib/selectors/user-selectors.js';

import { activeMessageListSelector } from '../navigation/nav-selectors.js';
import { NavContext } from '../navigation/navigation-context.js';
import { useSelector } from '../redux/redux-utils.js';
import { useForegroundActiveThread } from '../navigation/nav-selectors.js';

function DMActivityHandler(): React.Node {
const active = useSelector(
state => isLoggedIn(state) && state.lifecycleState !== 'background',
);
const navContext = React.useContext(NavContext);
const activeThread = React.useMemo(() => {
if (!active) {
return null;
}
return activeMessageListSelector(navContext);
}, [active, navContext]);

const activeThread = useForegroundActiveThread();
useDMActivityHandler(activeThread);
return null;
}
Expand Down
15 changes: 15 additions & 0 deletions native/navigation/nav-selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { createSelector } from 'reselect';

import { nonThreadCalendarFiltersSelector } from 'lib/selectors/calendar-filter-selectors.js';
import { currentCalendarQuery } from 'lib/selectors/nav-selectors.js';
import { isLoggedIn } from 'lib/selectors/user-selectors.js';
import { useCanEditMessage } from 'lib/shared/edit-messages-utils.js';
import type { CalendarQuery } from 'lib/types/entry-types.js';
import type { CalendarFilter } from 'lib/types/filter-types.js';
Expand Down Expand Up @@ -209,6 +210,19 @@ const activeMessageListSelector: (context: ?NavContextType) => ?string =
activeThread(navigationState, messageListRouteNames),
);

function useForegroundActiveThread(): ?string {
const active = useSelector(
state => isLoggedIn(state) && state.lifecycleState !== 'background',
);
const navContext = React.useContext(NavContext);
return React.useMemo(() => {
if (!active) {
return null;
}
return activeMessageListSelector(navContext);
}, [active, navContext]);
}

function useActiveThread(): ?string {
const navContext = React.useContext(NavContext);
return React.useMemo(() => {
Expand Down Expand Up @@ -442,4 +456,5 @@ export {
getTabNavState,
getChatNavStateFromTabNavState,
useCanEditMessageNative,
useForegroundActiveThread,
};
9 changes: 2 additions & 7 deletions native/socket.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js';
import { useDispatch } from 'lib/utils/redux-utils.js';

import {
activeMessageListSelector,
nativeCalendarQuery,
useForegroundActiveThread,
} from './navigation/nav-selectors.js';
import { NavContext } from './navigation/navigation-context.js';
import { useSelector } from './redux/redux-utils.js';
Expand Down Expand Up @@ -77,12 +77,7 @@ const NativeSocket: React.ComponentType<BaseSocketProps> =
}),
);

const activeThread = React.useMemo(() => {
if (!active) {
return null;
}
return activeMessageListSelector(navContext);
}, [active, navContext]);
const activeThread = useForegroundActiveThread();

const lastCommunicatedPlatformDetails = useSelector(
lastCommunicatedPlatformDetailsSelector(keyserverID),
Expand Down
17 changes: 3 additions & 14 deletions web/components/dm-activity-handler.react.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
// @flow

import * as React from 'react';

import useDMActivityHandler from 'lib/handlers/dm-activity-handler.js';
import { isLoggedIn } from 'lib/selectors/user-selectors.js';

import { useSelector } from '../redux/redux-utils.js';
import { activeThreadSelector } from '../selectors/nav-selectors.js';
import { foregroundActiveThreadSelector } from '../selectors/nav-selectors.js';

function DMActivityHandler(): React.Node {
const active = useSelector(
state => isLoggedIn(state) && state.lifecycleState !== 'background',
);
const reduxActiveThread = useSelector(activeThreadSelector);
const windowActive = useSelector(state => state.windowActive);
const activeThread = React.useMemo(() => {
if (!active || !windowActive) {
return null;
}
return reduxActiveThread;
}, [active, windowActive, reduxActiveThread]);

const activeThread = useSelector(foregroundActiveThreadSelector);
useDMActivityHandler(activeThread);
return null;
}
Expand Down
16 changes: 16 additions & 0 deletions web/selectors/nav-selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { createSelector } from 'reselect';

import { nonThreadCalendarFiltersSelector } from 'lib/selectors/calendar-filter-selectors.js';
import { currentCalendarQuery } from 'lib/selectors/nav-selectors.js';
import { isLoggedIn } from 'lib/selectors/user-selectors.js';
import type { CalendarQuery } from 'lib/types/entry-types.js';
import type { CalendarFilter } from 'lib/types/filter-types.js';
import type {
Expand Down Expand Up @@ -86,6 +87,20 @@ function activeThreadSelector(state: AppState): ?string {
return state.navInfo.tab === 'chat' ? state.navInfo.activeChatThreadID : null;
}

const foregroundActiveThreadSelector: (state: AppState) => ?string =
createSelector(
(state: AppState) =>
isLoggedIn(state) && state.lifecycleState !== 'background',
(state: AppState) => state.windowActive,
activeThreadSelector,
(active: boolean, windowActive: boolean, activeThread: ?string) => {
if (!active || !windowActive) {
return null;
}
return activeThread;
},
);

const webCalendarQuery: (state: AppState) => () => CalendarQuery =
createSelector(
currentCalendarQuery,
Expand Down Expand Up @@ -137,4 +152,5 @@ export {
nonThreadCalendarQuery,
navTabSelector,
navSettingsSectionSelector,
foregroundActiveThreadSelector,
};
11 changes: 2 additions & 9 deletions web/socket.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import { useDispatch } from 'lib/utils/redux-utils.js';
import { useNetworkConnected } from './redux/keyserver-reachability-handler.js';
import { useSelector } from './redux/redux-utils.js';
import {
activeThreadSelector,
webCalendarQuery,
foregroundActiveThreadSelector,
} from './selectors/nav-selectors.js';
import {
sessionIdentificationSelector,
Expand Down Expand Up @@ -65,14 +65,7 @@ const WebSocket: React.ComponentType<BaseSocketProps> =
);
const currentCalendarQuery = useSelector(webCalendarQuery);

const reduxActiveThread = useSelector(activeThreadSelector);
const windowActive = useSelector(state => state.windowActive);
const activeThread = React.useMemo(() => {
if (!active || !windowActive) {
return null;
}
return reduxActiveThread;
}, [active, windowActive, reduxActiveThread]);
const activeThread = useSelector(foregroundActiveThreadSelector);

const dispatch = useDispatch();
const dispatchActionPromise = useDispatchActionPromise();
Expand Down

0 comments on commit 7c7da1b

Please sign in to comment.