diff --git a/js/modules/signal.js b/js/modules/signal.js index a5c459f29..6a4206726 100644 --- a/js/modules/signal.js +++ b/js/modules/signal.js @@ -30,10 +30,10 @@ const { const { ContactListItem } = require('../../ts/components/ContactListItem'); const { ContactName } = require('../../ts/components/conversation/ContactName'); const { - ConversationHeader, + ConversationHeaderWithDetails, } = require('../../ts/components/conversation/ConversationHeader'); const { - SessionGroupSettings, + SessionGroupSettingsWithDetails, } = require('../../ts/components/session/SessionGroupSettings'); const { EmbeddedContact, @@ -275,8 +275,8 @@ exports.setup = (options = {}) => { ContactDetail, ContactListItem, ContactName, - ConversationHeader, - SessionGroupSettings, + ConversationHeaderWithDetails, + SessionGroupSettingsWithDetails, SettingsView, EmbeddedContact, Emojify, diff --git a/js/views/conversation_view.js b/js/views/conversation_view.js index 097556d16..a63b0e8d9 100644 --- a/js/views/conversation_view.js +++ b/js/views/conversation_view.js @@ -325,7 +325,7 @@ }; this.titleView = new Whisper.ReactWrapperView({ className: 'title-wrapper', - Component: window.Signal.Components.ConversationHeader, + Component: window.Signal.Components.ConversationHeaderWithDetails, props: getHeaderProps(), }); this.updateHeader = () => this.titleView.update(getHeaderProps()); @@ -359,7 +359,7 @@ if (!this.groupSettings) { this.groupSettings = new Whisper.ReactWrapperView({ className: 'group-settings', - Component: window.Signal.Components.SessionGroupSettings, + Component: window.Signal.Components.SessionGroupSettingsWithDetails, props: getGroupSettingsProps(this.model), }); this.$('.conversation-content-right').append(this.groupSettings.el); diff --git a/ts/components/ConversationListItem.tsx b/ts/components/ConversationListItem.tsx index a87b219e9..48206c2e9 100644 --- a/ts/components/ConversationListItem.tsx +++ b/ts/components/ConversationListItem.tsx @@ -20,10 +20,8 @@ import { getInviteContactMenuItem, getLeaveGroupMenuItem, } from '../session/utils/Menu'; -import { ConversationAttributes } from '../../js/models/conversations'; -import { GroupUtils } from '../session/utils'; -import { PubKey } from '../session/types'; -import { UserUtil } from '../util'; + +import { usingClosedConversationDetails } from './session/usingClosedConversationDetails'; export type PropsData = { id: string; @@ -57,6 +55,7 @@ export type PropsData = { isSecondary?: boolean; isGroupInvitation?: boolean; isKickedFromGroup?: boolean; + closedMemberConversations?: any; // this is added by usingClosedConversationDetails }; type PropsHousekeeping = { @@ -75,34 +74,9 @@ type PropsHousekeeping = { type Props = PropsData & PropsHousekeeping; -type State = { - closedMemberConversations?: Array; -}; - -export class ConversationListItem extends React.PureComponent { +class ConversationListItem extends React.PureComponent { public constructor(props: Props) { super(props); - this.state = { closedMemberConversations: undefined }; - } - - public componentDidMount() { - void this.fetchClosedConversationDetails(); - } - - public async fetchClosedConversationDetails() { - if (!this.props.isPublic && this.props.type === 'group') { - const groupId = this.props.phoneNumber; - let members = await GroupUtils.getGroupMembers(PubKey.cast(groupId)); - const ourPrimary = await UserUtil.getPrimary(); - members = members.filter(m => m.key !== ourPrimary.key); - members.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0)); - const membersConvos = members.map( - m => window.ConversationController.get(m.key).cachedProps - ); - // no need to forward more than 2 conversation for rendering the group avatar - membersConvos.slice(0, 2); - this.setState({ closedMemberConversations: membersConvos }); - } } public renderAvatar() { @@ -133,7 +107,7 @@ export class ConversationListItem extends React.PureComponent { profileName={profileName} size={iconSize} isPublic={isPublic} - closedMemberConversations={this.state.closedMemberConversations} + closedMemberConversations={this.props.closedMemberConversations} /> ); @@ -399,3 +373,7 @@ export class ConversationListItem extends React.PureComponent { ); } } + +export const ConversationListItemWithDetails = usingClosedConversationDetails( + ConversationListItem +); diff --git a/ts/components/SearchResults.tsx b/ts/components/SearchResults.tsx index 8532a3984..0791320e5 100644 --- a/ts/components/SearchResults.tsx +++ b/ts/components/SearchResults.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { - ConversationListItem, + ConversationListItemWithDetails, PropsData as ConversationListItemPropsType, } from './ConversationListItem'; import { @@ -62,7 +62,7 @@ export class SearchResults extends React.Component { {i18n('conversationsHeader')} {conversations.map(conversation => ( - {
{header}
{items.map(contact => ( - void; i18n: LocalizerType; + closedMemberConversations?: any; // this is added by usingClosedConversationDetails } -export class ConversationHeader extends React.Component { +class ConversationHeader extends React.Component { public showMenuBound: (event: React.MouseEvent) => void; public onAvatarClickBound: (userPubKey: string) => void; public menuTriggerRef: React.RefObject; @@ -196,6 +198,7 @@ export class ConversationHeader extends React.Component { public renderAvatar() { const { avatarPath, + closedMemberConversations, i18n, isGroup, isMe, @@ -217,11 +220,12 @@ export class ConversationHeader extends React.Component { name={name} phoneNumber={phoneNumber} profileName={profileName} - size={28} + size={36} onAvatarClick={() => { this.onAvatarClickBound(phoneNumber); }} isPublic={isPublic} + closedMemberConversations={closedMemberConversations} /> ); @@ -497,3 +501,7 @@ export class ConversationHeader extends React.Component { ); } } + +export const ConversationHeaderWithDetails = usingClosedConversationDetails( + ConversationHeader +); diff --git a/ts/components/session/LeftPaneContactSection.tsx b/ts/components/session/LeftPaneContactSection.tsx index 4490062e3..8ff7e85fc 100644 --- a/ts/components/session/LeftPaneContactSection.tsx +++ b/ts/components/session/LeftPaneContactSection.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { - ConversationListItem, + ConversationListItemWithDetails, PropsData as ConversationListItemPropsType, } from '../ConversationListItem'; import { PropsData as SearchResultsProps } from '../SearchResults'; @@ -116,7 +116,7 @@ export class LeftPaneContactSection extends React.Component { const item = contacts[index]; return ( - { const conversation = conversations[index]; return ( - void; onInviteContacts: () => void; @@ -33,7 +35,7 @@ interface Props { onSetDisappearingMessages: (seconds: number) => void; } -export class SessionGroupSettings extends React.Component { +class SessionGroupSettings extends React.Component { public constructor(props: Props) { super(props); @@ -309,6 +311,7 @@ export class SessionGroupSettings extends React.Component { private renderHeader() { const { + closedMemberConversations, id, onGoBack, onInviteContacts, @@ -336,6 +339,7 @@ export class SessionGroupSettings extends React.Component { conversationType="group" size={80} isPublic={isPublic} + closedMemberConversations={closedMemberConversations} />
{showInviteContacts && ( @@ -350,3 +354,7 @@ export class SessionGroupSettings extends React.Component { ); } } + +export const SessionGroupSettingsWithDetails = usingClosedConversationDetails( + SessionGroupSettings +); diff --git a/ts/components/session/usingClosedConversationDetails.tsx b/ts/components/session/usingClosedConversationDetails.tsx new file mode 100644 index 000000000..62f88cf7c --- /dev/null +++ b/ts/components/session/usingClosedConversationDetails.tsx @@ -0,0 +1,60 @@ +import { GroupUtils } from '../../session/utils'; +import { UserUtil } from '../../util'; +import { PubKey } from '../../session/types'; +import React from 'react'; +import { ConversationAttributes } from '../../../js/models/conversations'; +type State = { + closedMemberConversations?: Array; +}; + +export function usingClosedConversationDetails(WrappedComponent: any) { + return class extends React.Component { + constructor(props: any) { + super(props); + this.state = { + closedMemberConversations: undefined, + }; + } + + public componentDidMount() { + void this.fetchClosedConversationDetails(); + } + + public render() { + return ( + + ); + } + + private async fetchClosedConversationDetails() { + const { + isPublic, + type, + conversationType, + isGroup, + phoneNumber, + id, + } = this.props; + if ( + !isPublic && + (conversationType === 'group' || type === 'group' || isGroup) + ) { + console.warn('fetchClosedConversationDetails'); + const groupId = id || phoneNumber; + let members = await GroupUtils.getGroupMembers(PubKey.cast(groupId)); + const ourPrimary = await UserUtil.getPrimary(); + members = members.filter(m => m.key !== ourPrimary.key); + members.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0)); + const membersConvos = members.map( + m => window.ConversationController.get(m.key).cachedProps + ); + // no need to forward more than 2 conversation for rendering the group avatar + membersConvos.slice(0, 2); + this.setState({ closedMemberConversations: membersConvos }); + } + } + }; +}