mirror of
https://github.com/oxen-io/session-desktop.git
synced 2023-12-14 02:12:57 +01:00
use a HOC to fetch closed group conversations for avatar rendering
This commit is contained in:
parent
9584d0a1af
commit
b845ba9642
9 changed files with 101 additions and 47 deletions
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<ConversationAttributes>;
|
||||
};
|
||||
|
||||
export class ConversationListItem extends React.PureComponent<Props, State> {
|
||||
class ConversationListItem extends React.PureComponent<Props> {
|
||||
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<Props, State> {
|
|||
profileName={profileName}
|
||||
size={iconSize}
|
||||
isPublic={isPublic}
|
||||
closedMemberConversations={this.state.closedMemberConversations}
|
||||
closedMemberConversations={this.props.closedMemberConversations}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -399,3 +373,7 @@ export class ConversationListItem extends React.PureComponent<Props, State> {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const ConversationListItemWithDetails = usingClosedConversationDetails(
|
||||
ConversationListItem
|
||||
);
|
||||
|
|
|
@ -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<Props> {
|
|||
{i18n('conversationsHeader')}
|
||||
</div>
|
||||
{conversations.map(conversation => (
|
||||
<ConversationListItem
|
||||
<ConversationListItemWithDetails
|
||||
key={conversation.phoneNumber}
|
||||
{...conversation}
|
||||
onClick={openConversation}
|
||||
|
@ -106,7 +106,7 @@ export class SearchResults extends React.Component<Props> {
|
|||
<div className="module-search-results__contacts">
|
||||
<div className="module-search-results__contacts-header">{header}</div>
|
||||
{items.map(contact => (
|
||||
<ConversationListItem
|
||||
<ConversationListItemWithDetails
|
||||
key={contact.phoneNumber}
|
||||
{...contact}
|
||||
onClick={openConversation}
|
||||
|
|
|
@ -16,6 +16,7 @@ import {
|
|||
SessionButtonType,
|
||||
} from '../session/SessionButton';
|
||||
import * as Menu from '../../session/utils/Menu';
|
||||
import { usingClosedConversationDetails } from '../session/usingClosedConversationDetails';
|
||||
|
||||
export interface TimerOption {
|
||||
name: string;
|
||||
|
@ -91,9 +92,10 @@ interface Props {
|
|||
onUpdateGroupName: () => void;
|
||||
|
||||
i18n: LocalizerType;
|
||||
closedMemberConversations?: any; // this is added by usingClosedConversationDetails
|
||||
}
|
||||
|
||||
export class ConversationHeader extends React.Component<Props> {
|
||||
class ConversationHeader extends React.Component<Props> {
|
||||
public showMenuBound: (event: React.MouseEvent<HTMLDivElement>) => void;
|
||||
public onAvatarClickBound: (userPubKey: string) => void;
|
||||
public menuTriggerRef: React.RefObject<any>;
|
||||
|
@ -196,6 +198,7 @@ export class ConversationHeader extends React.Component<Props> {
|
|||
public renderAvatar() {
|
||||
const {
|
||||
avatarPath,
|
||||
closedMemberConversations,
|
||||
i18n,
|
||||
isGroup,
|
||||
isMe,
|
||||
|
@ -217,11 +220,12 @@ export class ConversationHeader extends React.Component<Props> {
|
|||
name={name}
|
||||
phoneNumber={phoneNumber}
|
||||
profileName={profileName}
|
||||
size={28}
|
||||
size={36}
|
||||
onAvatarClick={() => {
|
||||
this.onAvatarClickBound(phoneNumber);
|
||||
}}
|
||||
isPublic={isPublic}
|
||||
closedMemberConversations={closedMemberConversations}
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
|
@ -497,3 +501,7 @@ export class ConversationHeader extends React.Component<Props> {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const ConversationHeaderWithDetails = usingClosedConversationDetails(
|
||||
ConversationHeader
|
||||
);
|
||||
|
|
|
@ -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<Props, State> {
|
|||
const item = contacts[index];
|
||||
|
||||
return (
|
||||
<ConversationListItem
|
||||
<ConversationListItemWithDetails
|
||||
key={key}
|
||||
style={style}
|
||||
{...item}
|
||||
|
|
|
@ -4,7 +4,7 @@ import { AutoSizer, List } from 'react-virtualized';
|
|||
|
||||
import { MainViewController } from '../MainViewController';
|
||||
import {
|
||||
ConversationListItem,
|
||||
ConversationListItemWithDetails,
|
||||
PropsData as ConversationListItemPropsType,
|
||||
} from '../ConversationListItem';
|
||||
import { ConversationType } from '../../state/ducks/conversations';
|
||||
|
@ -113,7 +113,7 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
|
|||
const conversation = conversations[index];
|
||||
|
||||
return (
|
||||
<ConversationListItem
|
||||
<ConversationListItemWithDetails
|
||||
key={key}
|
||||
style={style}
|
||||
{...conversation}
|
||||
|
|
|
@ -10,6 +10,7 @@ import { SessionDropdown } from './SessionDropdown';
|
|||
import { MediaGallery } from '../conversation/media-gallery/MediaGallery';
|
||||
import _ from 'lodash';
|
||||
import { TimerOption } from '../conversation/ConversationHeader';
|
||||
import { usingClosedConversationDetails } from '../session/usingClosedConversationDetails';
|
||||
|
||||
interface Props {
|
||||
id: string;
|
||||
|
@ -23,6 +24,7 @@ interface Props {
|
|||
amMod: boolean;
|
||||
isKickedFromGroup: boolean;
|
||||
isBlocked: boolean;
|
||||
closedMemberConversations?: any; // this is added by usingClosedConversationDetails
|
||||
|
||||
onGoBack: () => void;
|
||||
onInviteContacts: () => void;
|
||||
|
@ -33,7 +35,7 @@ interface Props {
|
|||
onSetDisappearingMessages: (seconds: number) => void;
|
||||
}
|
||||
|
||||
export class SessionGroupSettings extends React.Component<Props, any> {
|
||||
class SessionGroupSettings extends React.Component<Props, any> {
|
||||
public constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
|
@ -309,6 +311,7 @@ export class SessionGroupSettings extends React.Component<Props, any> {
|
|||
|
||||
private renderHeader() {
|
||||
const {
|
||||
closedMemberConversations,
|
||||
id,
|
||||
onGoBack,
|
||||
onInviteContacts,
|
||||
|
@ -336,6 +339,7 @@ export class SessionGroupSettings extends React.Component<Props, any> {
|
|||
conversationType="group"
|
||||
size={80}
|
||||
isPublic={isPublic}
|
||||
closedMemberConversations={closedMemberConversations}
|
||||
/>
|
||||
<div className="invite-friends-container">
|
||||
{showInviteContacts && (
|
||||
|
@ -350,3 +354,7 @@ export class SessionGroupSettings extends React.Component<Props, any> {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const SessionGroupSettingsWithDetails = usingClosedConversationDetails(
|
||||
SessionGroupSettings
|
||||
);
|
||||
|
|
60
ts/components/session/usingClosedConversationDetails.tsx
Normal file
60
ts/components/session/usingClosedConversationDetails.tsx
Normal file
|
@ -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<ConversationAttributes>;
|
||||
};
|
||||
|
||||
export function usingClosedConversationDetails(WrappedComponent: any) {
|
||||
return class extends React.Component<any, State> {
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.state = {
|
||||
closedMemberConversations: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
void this.fetchClosedConversationDetails();
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<WrappedComponent
|
||||
closedMemberConversations={this.state.closedMemberConversations}
|
||||
{...this.props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
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 });
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue