Page MenuHomePhabricator

D8011.id27741.diff
No OneTemporary

D8011.id27741.diff

diff --git a/web/chat/chat-message-list-container.react.js b/web/chat/chat-message-list-container.react.js
--- a/web/chat/chat-message-list-container.react.js
+++ b/web/chat/chat-message-list-container.react.js
@@ -2,7 +2,6 @@
import classNames from 'classnames';
import invariant from 'invariant';
-import _isEqual from 'lodash/fp/isEqual.js';
import * as React from 'react';
import { useDrop } from 'react-dnd';
import { NativeTypes } from 'react-dnd-html5-backend';
@@ -28,46 +27,14 @@
function ChatMessageListContainer(props: Props): React.Node {
const { activeChatThreadID } = props;
- const {
- isChatCreation,
- selectedUserIDs,
- otherUserInfos,
- userInfoInputArray,
- } = useInfosForPendingThread();
+ const { isChatCreation, selectedUserInfos, otherUserInfos } =
+ useInfosForPendingThread();
const threadInfo = useThreadInfoForPossiblyPendingThread(activeChatThreadID);
invariant(threadInfo, 'ThreadInfo should be set');
const dispatch = useDispatch();
- // The effect removes members from list in navInfo
- // if some of the user IDs don't exist in redux store
- React.useEffect(() => {
- if (!isChatCreation) {
- return;
- }
- const existingSelectedUsersSet = new Set(
- userInfoInputArray.map(userInfo => userInfo.id),
- );
- if (
- selectedUserIDs?.length !== existingSelectedUsersSet.size ||
- !_isEqual(new Set(selectedUserIDs), existingSelectedUsersSet)
- ) {
- dispatch({
- type: updateNavInfoActionType,
- payload: {
- selectedUserList: Array.from(existingSelectedUsersSet),
- },
- });
- }
- }, [
- dispatch,
- isChatCreation,
- otherUserInfos,
- selectedUserIDs,
- userInfoInputArray,
- ]);
-
React.useEffect(() => {
if (isChatCreation && activeChatThreadID !== threadInfo?.id) {
let payload = {
@@ -158,14 +125,14 @@
}
const chatUserSelection = (
<ChatThreadComposer
- userInfoInputArray={userInfoInputArray}
+ userInfoInputArray={selectedUserInfos}
otherUserInfos={otherUserInfos}
threadID={threadInfo.id}
inputState={inputState}
/>
);
- if (!userInfoInputArray.length) {
+ if (!selectedUserInfos.length) {
return chatUserSelection;
}
return (
@@ -179,8 +146,8 @@
inputState,
isChatCreation,
otherUserInfos,
+ selectedUserInfos,
threadInfo,
- userInfoInputArray,
]);
return connectDropTarget(
diff --git a/web/chat/chat-thread-composer.react.js b/web/chat/chat-thread-composer.react.js
--- a/web/chat/chat-thread-composer.react.js
+++ b/web/chat/chat-thread-composer.react.js
@@ -1,5 +1,7 @@
// @flow
+
import classNames from 'classnames';
+import _isEqual from 'lodash/fp/isEqual.js';
import * as React from 'react';
import { useDispatch } from 'react-redux';
@@ -56,12 +58,11 @@
const userListItemsWithENSNames = useENSNames(userListItems);
const onSelectUserFromSearch = React.useCallback(
- (id: string) => {
- const selectedUserIDs = userInfoInputArray.map(user => user.id);
+ (user: AccountUserInfo) => {
dispatch({
type: updateNavInfoActionType,
payload: {
- selectedUserList: [...selectedUserIDs, id],
+ selectedUserList: [...userInfoInputArray, user],
},
});
setUsernameInputText('');
@@ -70,15 +71,17 @@
);
const onRemoveUserFromSelected = React.useCallback(
- (id: string) => {
- const selectedUserIDs = userInfoInputArray.map(user => user.id);
- if (!selectedUserIDs.includes(id)) {
+ (userID: string) => {
+ const newSelectedUserList = userInfoInputArray.filter(
+ ({ id }) => userID !== id,
+ );
+ if (_isEqual(userInfoInputArray)(newSelectedUserList)) {
return;
}
dispatch({
type: updateNavInfoActionType,
payload: {
- selectedUserList: selectedUserIDs.filter(userID => userID !== id),
+ selectedUserList: newSelectedUserList,
},
});
},
@@ -94,21 +97,25 @@
}
const userItems = userListItemsWithENSNames.map(
- (userSearchResult: UserListItem) => (
- <li key={userSearchResult.id} className={css.searchResultsItem}>
- <Button
- variant="text"
- onClick={() => onSelectUserFromSearch(userSearchResult.id)}
- className={css.searchResultsButton}
- >
- <div className={css.userContainer}>
- <UserAvatar size="small" userID={userSearchResult.id} />
- <div className={css.userName}>{userSearchResult.username}</div>
- </div>
- <div className={css.userInfo}>{userSearchResult.alertTitle}</div>
- </Button>
- </li>
- ),
+ (userSearchResult: UserListItem) => {
+ const { alertTitle, alertText, notice, disabled, ...accountUserInfo } =
+ userSearchResult;
+ return (
+ <li key={userSearchResult.id} className={css.searchResultsItem}>
+ <Button
+ variant="text"
+ onClick={() => onSelectUserFromSearch(accountUserInfo)}
+ className={css.searchResultsButton}
+ >
+ <div className={css.userContainer}>
+ <UserAvatar size="small" userID={userSearchResult.id} />
+ <div className={css.userName}>{userSearchResult.username}</div>
+ </div>
+ <div className={css.userInfo}>{userSearchResult.alertTitle}</div>
+ </Button>
+ </li>
+ );
+ },
);
return <ul className={css.searchResultsContainer}>{userItems}</ul>;
diff --git a/web/types/nav-types.js b/web/types/nav-types.js
--- a/web/types/nav-types.js
+++ b/web/types/nav-types.js
@@ -7,6 +7,10 @@
type ThreadInfo,
threadInfoValidator,
} from 'lib/types/thread-types.js';
+import {
+ type AccountUserInfo,
+ accountUserInfoValidator,
+} from 'lib/types/user-types.js';
import { tID, tShape } from 'lib/utils/validation-utils.js';
export type NavigationTab = 'calendar' | 'chat' | 'settings';
@@ -27,7 +31,7 @@
+activeChatThreadID: ?string,
+pendingThread?: ThreadInfo,
+settingsSection?: NavigationSettingsSection,
- +selectedUserList?: $ReadOnlyArray<string>,
+ +selectedUserList?: $ReadOnlyArray<AccountUserInfo>,
+chatMode?: NavigationChatMode,
+inviteSecret?: ?string,
};
@@ -39,7 +43,7 @@
activeChatThreadID: t.maybe(tID),
pendingThread: t.maybe(threadInfoValidator),
settingsSection: t.maybe(navigationSettingsSectionValidator),
- selectedUserList: t.maybe(t.list(t.String)),
+ selectedUserList: t.maybe(t.list(accountUserInfoValidator)),
chatMode: t.maybe(navigationChatModeValidator),
inviteSecret: t.maybe(t.String),
});
diff --git a/web/url-utils.js b/web/url-utils.js
--- a/web/url-utils.js
+++ b/web/url-utils.js
@@ -1,6 +1,7 @@
// @flow
import invariant from 'invariant';
+import _keyBy from 'lodash/fp/keyBy.js';
import {
startDateForYearAndMonth,
@@ -55,7 +56,8 @@
}
} else if (navInfo.tab === 'chat') {
if (navInfo.chatMode === 'create') {
- const users = navInfo.selectedUserList?.join('+') ?? '';
+ const users =
+ navInfo.selectedUserList?.map(({ id }) => id)?.join('+') ?? '';
const potentiallyTrailingSlash = users.length > 0 ? '/' : '';
newURL += `thread/new/${users}${potentiallyTrailingSlash}`;
} else {
@@ -126,7 +128,10 @@
};
if (urlInfo.selectedUserList) {
- newNavInfo.selectedUserList = urlInfo.selectedUserList;
+ const selectedUsers = _keyBy('id')(navInfo?.selectedUserList ?? []);
+ newNavInfo.selectedUserList = urlInfo.selectedUserList
+ ?.map(id => selectedUsers[id])
+ ?.filter(Boolean);
}
if (urlInfo.settings) {
diff --git a/web/utils/thread-utils.js b/web/utils/thread-utils.js
--- a/web/utils/thread-utils.js
+++ b/web/utils/thread-utils.js
@@ -18,33 +18,29 @@
type InfosForPendingThread = {
+isChatCreation: boolean,
- +selectedUserIDs: ?$ReadOnlyArray<string>,
+ +selectedUserInfos: $ReadOnlyArray<AccountUserInfo>,
+otherUserInfos: { [id: string]: AccountUserInfo },
- +userInfoInputArray: $ReadOnlyArray<AccountUserInfo>,
};
function useInfosForPendingThread(): InfosForPendingThread {
const isChatCreation = useSelector(
state => state.navInfo.chatMode === 'create',
);
- const selectedUserIDs = useSelector(state => state.navInfo.selectedUserList);
- const otherUserInfos = useSelector(userInfoSelectorForPotentialMembers);
- const userInfoInputArray: $ReadOnlyArray<AccountUserInfo> = React.useMemo(
- () => selectedUserIDs?.map(id => otherUserInfos[id]).filter(Boolean) ?? [],
- [otherUserInfos, selectedUserIDs],
+ const selectedUserInfos = useSelector(
+ state => state.navInfo.selectedUserList ?? [],
);
+ const otherUserInfos = useSelector(userInfoSelectorForPotentialMembers);
return {
isChatCreation,
- selectedUserIDs,
+ selectedUserInfos,
otherUserInfos,
- userInfoInputArray,
};
}
function useThreadInfoForPossiblyPendingThread(
activeChatThreadID: ?string,
): ?ThreadInfo {
- const { isChatCreation, userInfoInputArray } = useInfosForPendingThread();
+ const { isChatCreation, selectedUserInfos } = useInfosForPendingThread();
const loggedInUserInfo = useLoggedInUserInfo();
invariant(loggedInUserInfo, 'loggedInUserInfo should be set');
@@ -86,13 +82,13 @@
const existingThreadInfoFinder = useExistingThreadInfoFinder(baseThreadInfo);
const threadInfo = React.useMemo(() => {
if (isChatCreation) {
- if (userInfoInputArray.length === 0) {
+ if (selectedUserInfos.length === 0) {
return pendingNewThread;
}
return existingThreadInfoFinderForCreatingThread({
searching: true,
- userInfoInputArray,
+ userInfoInputArray: selectedUserInfos,
});
}
@@ -104,8 +100,8 @@
existingThreadInfoFinder,
existingThreadInfoFinderForCreatingThread,
isChatCreation,
- userInfoInputArray,
pendingNewThread,
+ selectedUserInfos,
]);
return threadInfo;

File Metadata

Mime Type
text/plain
Expires
Tue, Dec 3, 9:34 AM (20 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2611184
Default Alt Text
D8011.id27741.diff (9 KB)

Event Timeline