cleanedup redux action openConversationExternal

This commit is contained in:
Audric Ackermann 2021-07-08 16:12:58 +10:00
parent 7f76ab274c
commit ee4a0b9b1e
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4
19 changed files with 208 additions and 281 deletions

View File

@ -16,15 +16,15 @@ import { OutgoingMessageStatus } from './conversation/message/OutgoingMessageSta
import { useTheme } from 'styled-components';
import { PubKey } from '../session/types';
import {
ConversationType,
LastMessageType,
openConversationExternal,
ReduxConversationType,
} from '../state/ducks/conversations';
import _ from 'underscore';
import { useMembersAvatars } from '../hooks/useMembersAvatar';
import { useDispatch } from 'react-redux';
export interface ConversationListItemProps extends ConversationType {}
export interface ConversationListItemProps extends ReduxConversationType {}
type PropsHousekeeping = {
style?: Object;

View File

@ -1,9 +1,8 @@
import React, { useState } from 'react';
import React from 'react';
import { ActionsPanel, SectionType } from './session/ActionsPanel';
import { LeftPaneMessageSection } from './session/LeftPaneMessageSection';
import { openConversationExternal } from '../state/ducks/conversations';
import { LeftPaneContactSection } from './session/LeftPaneContactSection';
import { LeftPaneSettingSection } from './session/LeftPaneSettingSection';
import { SessionTheme } from '../state/ducks/SessionTheme';
@ -13,6 +12,7 @@ import { useDispatch, useSelector } from 'react-redux';
import { getLeftPaneLists } from '../state/selectors/conversations';
import { getQuery, getSearchResults, isSearching } from '../state/selectors/search';
import { clearSearch, search, updateSearchTerm } from '../state/ducks/search';
import { useTheme } from 'styled-components';
import { getTheme } from '../state/selectors/theme';
// from https://github.com/bvaughn/react-virtualized/blob/fb3484ed5dcc41bffae8eab029126c0fb8f7abc0/source/List/types.js#L5
@ -30,57 +30,29 @@ type Props = {
};
const InnerLeftPaneMessageSection = (props: { isExpired: boolean }) => {
const dispatch = useDispatch();
const showSearch = useSelector(isSearching);
const searchTerm = useSelector(getQuery);
const searchResults = showSearch ? useSelector(getSearchResults) : undefined;
const lists = showSearch ? undefined : useSelector(getLeftPaneLists);
const theme = useSelector(getTheme);
// tslint:disable: use-simple-attributes
return (
<>
{props.isExpired && <SessionExpiredWarning />}
<LeftPaneMessageSection
theme={theme}
openConversationExternal={(id, messageId) =>
dispatch(openConversationExternal(id, messageId))
}
conversations={lists?.conversations || []}
contacts={lists?.contacts || []}
searchResults={searchResults}
searchTerm={searchTerm}
updateSearchTerm={query => dispatch(updateSearchTerm(query))}
search={(query, options) => dispatch(search(query, options))}
clearSearch={() => dispatch(clearSearch())}
/>
</>
);
};
const InnerLeftPaneContactSection = () => {
const dispatch = useDispatch();
const theme = useSelector(getTheme);
const showSearch = useSelector(isSearching);
const lists = showSearch ? undefined : useSelector(getLeftPaneLists);
const directContacts = lists?.contacts || [];
return (
<>
<LeftPaneContactSection
openConversationExternal={(id, messageId) =>
dispatch(openConversationExternal(id, messageId))
}
directContacts={directContacts}
theme={theme}
/>
</>
);
return <LeftPaneContactSection />;
};
const LeftPaneSection = (props: { isExpired: boolean }) => {
@ -96,23 +68,21 @@ const LeftPaneSection = (props: { isExpired: boolean }) => {
if (focusedSection === SectionType.Settings) {
return <LeftPaneSettingSection />;
}
return <></>;
return null;
};
export const LeftPane = (props: Props) => {
const theme = useSelector(getTheme);
return (
<>
<SessionTheme theme={theme}>
<div className="module-left-pane-session">
<ActionsPanel />
<SessionTheme theme={theme}>
<div className="module-left-pane-session">
<ActionsPanel />
<div className="module-left-pane">
<LeftPaneSection isExpired={props.isExpired} />
</div>
<div className="module-left-pane">
<LeftPaneSection isExpired={props.isExpired} />
</div>
</SessionTheme>
</>
</div>
</SessionTheme>
);
};

View File

@ -14,70 +14,58 @@ export type SearchResultsProps = {
searchTerm: string;
};
type PropsHousekeeping = {
openConversationExternal: (id: string, messageId?: string) => void;
const ContactsItem = (props: { header: string; items: Array<ConversationListItemProps> }) => {
return (
<div className="module-search-results__contacts">
<div className="module-search-results__contacts-header">{props.header}</div>
{props.items.map(contact => (
<MemoConversationListItemWithDetails {...contact} />
))}
</div>
);
};
type Props = SearchResultsProps & PropsHousekeeping;
export const SearchResults = (props: SearchResultsProps) => {
const { conversations, contacts, hideMessagesHeader, messages, searchTerm } = props;
export class SearchResults extends React.Component<Props> {
public render() {
const {
conversations,
contacts,
hideMessagesHeader,
messages,
openConversationExternal,
searchTerm,
} = this.props;
const haveConversations = conversations && conversations.length;
const haveContacts = contacts && contacts.length;
const haveMessages = messages && messages.length;
const noResults = !haveConversations && !haveContacts && !haveMessages;
const haveConversations = conversations && conversations.length;
const haveContacts = contacts && contacts.length;
const haveMessages = messages && messages.length;
const noResults = !haveConversations && !haveContacts && !haveMessages;
return (
<div className="module-search-results">
{noResults ? (
<div className="module-search-results__no-results">
{window.i18n('noSearchResults', [searchTerm])}
return (
<div className="module-search-results">
{noResults ? (
<div className="module-search-results__no-results">
{window.i18n('noSearchResults', [searchTerm])}
</div>
) : null}
{haveConversations ? (
<div className="module-search-results__conversations">
<div className="module-search-results__conversations-header">
{window.i18n('conversationsHeader')}
</div>
) : null}
{haveConversations ? (
<div className="module-search-results__conversations">
<div className="module-search-results__conversations-header">
{window.i18n('conversationsHeader')}
{conversations.map(conversation => (
<MemoConversationListItemWithDetails {...conversation} />
))}
</div>
) : null}
{haveContacts ? (
<ContactsItem header={window.i18n('contactsHeader')} items={contacts} />
) : null}
{haveMessages ? (
<div className="module-search-results__messages">
{hideMessagesHeader ? null : (
<div className="module-search-results__messages-header">
{window.i18n('messagesHeader')}
</div>
{conversations.map(conversation => (
<MemoConversationListItemWithDetails {...conversation} />
))}
</div>
) : null}
{haveContacts ? this.renderContacts(window.i18n('contactsHeader'), contacts) : null}
{haveMessages ? (
<div className="module-search-results__messages">
{hideMessagesHeader ? null : (
<div className="module-search-results__messages-header">
{window.i18n('messagesHeader')}
</div>
)}
{messages.map(message => (
<MessageSearchResult key={message.id} {...message} />
))}
</div>
) : null}
</div>
);
}
private renderContacts(header: string, items: Array<ConversationListItemProps>) {
return (
<div className="module-search-results__contacts">
<div className="module-search-results__contacts-header">{header}</div>
{items.map(contact => (
<MemoConversationListItemWithDetails {...contact} />
))}
</div>
);
}
}
)}
{messages.map(message => (
<MessageSearchResult key={message.id} {...message} />
))}
</div>
) : null}
</div>
);
};

View File

@ -3,70 +3,58 @@ import React from 'react';
import { MemoConversationListItemWithDetails } from '../ConversationListItem';
import { RowRendererParamsType } from '../LeftPane';
import { AutoSizer, List } from 'react-virtualized';
import { ConversationType as ReduxConversationType } from '../../state/ducks/conversations';
import { DefaultTheme } from 'styled-components';
import { LeftPaneSectionHeader } from './LeftPaneSectionHeader';
import autoBind from 'auto-bind';
import { useSelector } from 'react-redux';
import { getDirectContacts, getLeftPaneLists } from '../../state/selectors/conversations';
import { isSearching } from '../../state/selectors/search';
export interface Props {
directContacts: Array<ReduxConversationType>;
theme: DefaultTheme;
openConversationExternal: (id: string, messageId?: string) => void;
}
const renderRow = ({ index, key, style }: RowRendererParamsType): JSX.Element | undefined => {
const showSearch = useSelector(isSearching);
export class LeftPaneContactSection extends React.Component<Props> {
public constructor(props: Props) {
super(props);
autoBind(this);
const lists = showSearch ? undefined : useSelector(getLeftPaneLists);
const directContacts = lists?.contacts || [];
const item = directContacts[index];
return <MemoConversationListItemWithDetails style={style} key={key} {...item} />;
};
const ContactListItemSection = () => {
const directContacts = useSelector(getDirectContacts);
if (!directContacts) {
return null;
}
const length = Number(directContacts.length);
public renderHeader(): JSX.Element | undefined {
return <LeftPaneSectionHeader label={window.i18n('contactsHeader')} theme={this.props.theme} />;
}
return (
<div className="module-left-pane__list" key={0}>
<AutoSizer>
{({ height, width }) => (
<List
className="module-left-pane__virtual-list"
height={height}
directContacts={directContacts} // needed for change in props refresh
rowCount={length}
rowHeight={64}
rowRenderer={renderRow}
width={width}
autoHeight={false}
/>
)}
</AutoSizer>
</div>
);
};
public render(): JSX.Element {
return (
<div className="left-pane-contact-section">
{this.renderHeader()}
{this.renderContacts()}
export const LeftPaneContactSection = () => {
debugger;
return (
<div className="left-pane-contact-section">
<LeftPaneSectionHeader label={window.i18n('contactsHeader')} />
<div className="left-pane-contact-content">
<ContactListItemSection />
</div>
);
}
public renderRow = ({ index, key, style }: RowRendererParamsType): JSX.Element | undefined => {
const { directContacts } = this.props;
const item = directContacts[index];
return <MemoConversationListItemWithDetails style={style} {...item} />;
};
private renderContacts() {
return <div className="left-pane-contact-content">{this.renderList()}</div>;
}
private renderList() {
const { directContacts } = this.props;
const length = Number(directContacts.length);
const list = (
<div className="module-left-pane__list" key={0}>
<AutoSizer>
{({ height, width }) => (
<List
className="module-left-pane__virtual-list"
height={height}
directContacts={directContacts} // needed for change in props refresh
rowCount={length}
rowHeight={64}
rowRenderer={this.renderRow}
width={width}
autoHeight={false}
/>
)}
</AutoSizer>
</div>
);
return [list];
}
}
</div>
);
};

View File

@ -7,7 +7,7 @@ import {
ConversationListItemProps,
MemoConversationListItemWithDetails,
} from '../ConversationListItem';
import { ConversationType as ReduxConversationType } from '../../state/ducks/conversations';
import { openConversationExternal, ReduxConversationType } from '../../state/ducks/conversations';
import { SearchResults, SearchResultsProps } from '../SearchResults';
import { SessionSearchInput } from './SessionSearchInput';
import { debounce } from 'lodash';
@ -29,8 +29,7 @@ import { joinOpenGroupV2WithUIEvents } from '../../opengroup/opengroupV2/JoinOpe
import autoBind from 'auto-bind';
import { onsNameRegex } from '../../session/snode_api/SNodeAPI';
import { SNodeAPI } from '../../session/snode_api';
import { createClosedGroup } from '../../receiver/closedGroups';
import { clearSearch, search, updateSearchTerm } from '../../state/ducks/search';
export interface Props {
searchTerm: string;
@ -38,12 +37,6 @@ export interface Props {
contacts: Array<ReduxConversationType>;
conversations?: Array<ConversationListItemProps>;
searchResults?: SearchResultsProps;
updateSearchTerm: (searchTerm: string) => void;
search: (query: string, options: SearchOptions) => void;
openConversationExternal: (id: string, messageId?: string) => void;
clearSearch: () => void;
theme: DefaultTheme;
}
export enum SessionComposeToType {
@ -81,7 +74,7 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
}
public renderRow = ({ index, key, style }: RowRendererParamsType): JSX.Element => {
const { conversations, openConversationExternal } = this.props;
const { conversations } = this.props;
if (!conversations) {
throw new Error('renderRow: Tried to render without conversations');
@ -89,21 +82,15 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
const conversation = conversations[index];
return <MemoConversationListItemWithDetails style={style} {...conversation} />;
return <MemoConversationListItemWithDetails key={key} style={style} {...conversation} />;
};
public renderList(): JSX.Element | Array<JSX.Element | null> {
const { conversations, openConversationExternal, searchResults } = this.props;
const { conversations, searchResults } = this.props;
const contacts = searchResults?.contacts || [];
if (searchResults) {
return (
<SearchResults
{...searchResults}
contacts={contacts}
openConversationExternal={openConversationExternal}
/>
);
return <SearchResults {...searchResults} contacts={contacts} />;
}
if (!conversations) {
@ -147,7 +134,6 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
return (
<LeftPaneSectionHeader
label={window.i18n('messagesHeader')}
theme={this.props.theme}
buttonIcon={SessionIconType.Plus}
buttonClicked={this.handleNewSessionButtonClick}
/>
@ -172,7 +158,6 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
searchString={this.props.searchTerm}
onChange={this.updateSearch}
placeholder={window.i18n('searchFor...')}
theme={this.props.theme}
/>
{this.renderList()}
{this.renderBottomButtons()}
@ -181,10 +166,8 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
}
public updateSearch(searchTerm: string) {
const { updateSearchTerm, clearSearch } = this.props;
if (!searchTerm) {
clearSearch();
window.inboxStore?.dispatch(clearSearch());
return;
}
@ -192,9 +175,7 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
// reset our pubKeyPasted, we can either have a pasted sessionID or a sessionID got from a search
this.setState({ valuePasted: '' });
if (updateSearchTerm) {
updateSearchTerm(searchTerm);
}
window.inboxStore?.dispatch(updateSearchTerm(searchTerm));
if (searchTerm.length < 2) {
return;
@ -209,19 +190,17 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
}
public clearSearch() {
this.props.clearSearch();
window.inboxStore?.dispatch(clearSearch());
}
public search() {
const { search } = this.props;
const { searchTerm } = this.props;
if (search) {
window.inboxStore?.dispatch(
search(searchTerm, {
noteToSelf: window.i18n('noteToSelf').toLowerCase(),
ourNumber: UserUtils.getOurPubKeyStrFromCache(),
});
}
})
);
}
private renderClosableOverlay(overlay: SessionComposeToType) {
@ -239,7 +218,6 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
searchTerm={searchTerm}
updateSearch={this.updateSearch}
showSpinner={loading}
theme={this.props.theme}
/>
);
@ -257,7 +235,6 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
searchTerm={searchTerm}
updateSearch={this.updateSearch}
showSpinner={loading}
theme={this.props.theme}
/>
);
@ -273,7 +250,6 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
searchResults={searchResults}
showSpinner={loading}
updateSearch={this.updateSearch}
theme={this.props.theme}
/>
);
@ -332,8 +308,6 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
}
private async handleMessageButtonClick() {
const { openConversationExternal } = this.props;
if (!this.state.valuePasted && !this.props.searchTerm) {
ToastUtils.pushToastError('invalidPubKey', window.i18n('invalidNumberError')); // or ons name
return;
@ -349,7 +323,7 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
pubkeyorOns,
ConversationTypeEnum.PRIVATE
);
openConversationExternal(pubkeyorOns);
window.inboxStore?.dispatch(openConversationExternal(pubkeyorOns));
this.handleToggleOverlay(undefined);
} else {
// this might be an ONS, validate the regex first
@ -369,7 +343,7 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
resolvedSessionID,
ConversationTypeEnum.PRIVATE
);
openConversationExternal(resolvedSessionID);
window.inboxStore?.dispatch(openConversationExternal(resolvedSessionID));
this.handleToggleOverlay(undefined);
} catch (e) {
window?.log?.warn('failed to resolve ons name', pubkeyorOns, e);

View File

@ -1,7 +1,7 @@
import React from 'react';
import classNames from 'classnames';
import { SessionIcon, SessionIconSize, SessionIconType } from './icon';
import { DefaultTheme } from 'styled-components';
import { DefaultTheme, useTheme } from 'styled-components';
import { SessionButton } from './SessionButton';
const Tab = ({
@ -36,22 +36,23 @@ type Props = {
label?: string;
buttonIcon?: SessionIconType;
buttonClicked?: any;
theme: DefaultTheme;
};
export const LeftPaneSectionHeader = (props: Props) => {
const { label, buttonIcon, buttonClicked } = props;
const theme = useTheme();
return (
<div className="module-left-pane__header">
{label && <Tab label={label} type={0} isSelected={true} key={label} />}
{buttonIcon && (
<SessionButton onClick={buttonClicked} key="compose" theme={props.theme}>
<SessionButton onClick={buttonClicked} key="compose" theme={theme}>
<SessionIcon
iconType={buttonIcon}
iconSize={SessionIconSize.Small}
iconColor="white"
theme={props.theme}
theme={theme}
/>
</SessionButton>
)}

View File

@ -154,7 +154,7 @@ export const LeftPaneSettingSection = () => {
const theme = useSelector(getTheme);
return (
<div className="left-pane-setting-section">
<LeftPaneSectionHeader label={window.i18n('settingsHeader')} theme={theme} />
<LeftPaneSectionHeader label={window.i18n('settingsHeader')} />
<div className="left-pane-setting-content">
<LeftPaneSettingsCategories />
<LeftPaneBottomButtons />

View File

@ -4,7 +4,7 @@ import { SessionIconButton, SessionIconSize, SessionIconType } from './icon';
import { SessionIdEditable } from './SessionIdEditable';
import { UserSearchDropdown } from './UserSearchDropdown';
import { ContactType, SessionMemberListItem } from './SessionMemberListItem';
import { ConversationType } from '../../state/ducks/conversations';
import { ReduxConversationType } from '../../state/ducks/conversations';
import { SessionButton, SessionButtonColor, SessionButtonType } from './SessionButton';
import { SessionSpinner } from './SessionSpinner';
import { DefaultTheme } from 'styled-components';
@ -23,12 +23,11 @@ interface Props {
onChangeSessionID: any;
onCloseClick: any;
onButtonClick: any;
contacts?: Array<ConversationType>;
contacts?: Array<ReduxConversationType>;
searchTerm?: string;
searchResults?: any;
updateSearch?: any;
showSpinner?: boolean;
theme: DefaultTheme;
}
interface State {
@ -159,7 +158,6 @@ export class SessionClosableOverlay extends React.Component<Props, State> {
iconSize={SessionIconSize.Small}
iconType={SessionIconType.Exit}
onClick={onCloseClick}
theme={this.props.theme}
/>
</div>
@ -226,7 +224,6 @@ export class SessionClosableOverlay extends React.Component<Props, State> {
updateSearch={updateSearch}
placeholder={window.i18n('searchFor...')}
searchResults={searchResults}
theme={this.props.theme}
/>
)}

View File

@ -8,7 +8,6 @@ interface Props {
onChange: any;
handleNavigation?: any;
placeholder: string;
theme: DefaultTheme;
}
export class SessionSearchInput extends React.Component<Props> {
@ -32,11 +31,7 @@ export class SessionSearchInput extends React.Component<Props> {
});
}}
>
<SessionIconButton
iconSize={SessionIconSize.Medium}
iconType={SessionIconType.Search}
theme={this.props.theme}
/>
<SessionIconButton iconSize={SessionIconSize.Medium} iconType={SessionIconType.Search} />
<input
value={searchString}
onChange={e => this.props.onChange(e.target.value)}

View File

@ -11,7 +11,6 @@ export interface Props {
placeholder: string;
searchResults?: SearchResultsProps;
updateSearch: (searchTerm: string) => void;
theme: DefaultTheme;
}
interface State {
@ -68,7 +67,6 @@ export class UserSearchDropdown extends React.Component<Props, State> {
onChange={this.updateSearchBound}
placeholder={placeholder}
handleNavigation={this.handleNavigation}
theme={this.props.theme}
/>
{searchResults && (
<UserSearchResults

View File

@ -28,7 +28,7 @@ import { Mention, MentionsInput } from 'react-mentions';
import { CaptionEditor } from '../../CaptionEditor';
import { DefaultTheme } from 'styled-components';
import { getConversationController } from '../../../session/conversations';
import { ConversationType } from '../../../state/ducks/conversations';
import { ReduxConversationType } from '../../../state/ducks/conversations';
import { SessionMemberListItem } from '../SessionMemberListItem';
import autoBind from 'auto-bind';
import { SectionType } from '../ActionsPanel';
@ -72,7 +72,7 @@ interface Props {
isKickedFromGroup: boolean;
left: boolean;
selectedConversationKey: string;
selectedConversation: ConversationType | undefined;
selectedConversation: ReduxConversationType | undefined;
isPublic: boolean;
quotedMessageProps?: ReplyingToMessageProps;

View File

@ -23,7 +23,7 @@ import { ToastUtils, UserUtils } from '../../../session/utils';
import * as MIME from '../../../types/MIME';
import { SessionFileDropzone } from './SessionFileDropzone';
import {
ConversationType,
ReduxConversationType,
PropsForMessage,
SortedMessageModelProps,
} from '../../../state/ducks/conversations';
@ -40,6 +40,7 @@ import { updateMentionsMembers } from '../../../state/ducks/mentionsInput';
import { sendDataExtractionNotification } from '../../../session/messages/outgoing/controlMessage/DataExtractionNotificationMessage';
import { SessionButtonColor } from '../SessionButton';
import { updateConfirmModal } from '../../../state/ducks/modalDialog';
interface State {
unreadCount: number;
selectedMessages: Array<string>;
@ -70,10 +71,9 @@ export interface LightBoxOptions {
interface Props {
ourNumber: string;
selectedConversationKey: string;
selectedConversation?: ConversationType;
selectedConversation?: ReduxConversationType;
theme: DefaultTheme;
messagesProps: Array<SortedMessageModelProps>;
actions: any;
}
export class SessionConversation extends React.Component<Props, State> {
@ -199,7 +199,7 @@ export class SessionConversation extends React.Component<Props, State> {
} = this.state;
const selectionMode = !!selectedMessages.length;
const { selectedConversation, selectedConversationKey, messagesProps, actions } = this.props;
const { selectedConversation, selectedConversationKey, messagesProps } = this.props;
if (!selectedConversation || !messagesProps) {
// return an empty message view
@ -227,9 +227,6 @@ export class SessionConversation extends React.Component<Props, State> {
};
const showMessageDetails = !!messageDetailShowProps;
const isPublic = selectedConversation.isPublic || false;
const isPrivate = selectedConversation.type === ConversationTypeEnum.PRIVATE;
return (
<SessionTheme theme={this.props.theme}>
<div className="conversation-header">{this.renderHeader()}</div>
@ -257,8 +254,8 @@ export class SessionConversation extends React.Component<Props, State> {
isBlocked={selectedConversation.isBlocked}
left={selectedConversation.left}
isKickedFromGroup={selectedConversation.isKickedFromGroup}
isPrivate={isPrivate}
isPublic={isPublic}
isPrivate={selectedConversation.isPrivate}
isPublic={selectedConversation.isPublic}
selectedConversationKey={selectedConversationKey}
selectedConversation={selectedConversation}
sendMessage={sendMessageFn}
@ -307,10 +304,12 @@ export class SessionConversation extends React.Component<Props, State> {
Constants.CONVERSATION.DEFAULT_MESSAGE_FETCH_COUNT,
unreadCount
);
this.props.actions.fetchMessagesForConversation({
conversationKey: selectedConversationKey,
count: messagesToFetch,
});
window.inboxStore?.dispatch(
fetchMessagesForConversation({
conversationKey: selectedConversationKey,
count: messagesToFetch,
})
);
}
public getHeaderProps(): ConversationHeaderNonReduxProps {
@ -337,6 +336,9 @@ export class SessionConversation extends React.Component<Props, State> {
const { selectedConversation, selectedConversationKey, ourNumber, messagesProps } = this.props;
const { quotedMessageTimestamp, selectedMessages } = this.state;
if (!selectedConversation) {
throw new Error();
}
return {
selectedMessages,
ourPrimary: ourNumber,
@ -344,7 +346,7 @@ export class SessionConversation extends React.Component<Props, State> {
messagesProps,
resetSelection: this.resetSelection,
quotedMessageTimestamp,
conversation: selectedConversation as ConversationType,
conversation: selectedConversation,
selectMessage: this.selectMessage,
deleteMessage: this.deleteMessage,
replyToMessage: this.replyToMessage,
@ -490,18 +492,19 @@ export class SessionConversation extends React.Component<Props, State> {
if (askUserForConfirmation) {
const onClickClose = () => {
this.props.actions.updateConfirmModal(null);
window.inboxStore?.dispatch(updateConfirmModal(null));
};
this.props.actions.updateConfirmModal({
title,
message: warningMessage,
okText,
okTheme: SessionButtonColor.Danger,
onClickOk: doDelete,
onClickClose,
closeAfterClick: true,
});
window.inboxStore?.dispatch(
updateConfirmModal({
title,
message: warningMessage,
okText,
okTheme: SessionButtonColor.Danger,
onClickOk: doDelete,
onClickClose,
})
);
} else {
void doDelete();
}
@ -988,3 +991,6 @@ export class SessionConversation extends React.Component<Props, State> {
window.inboxStore?.dispatch(updateMentionsMembers(allMembers));
}
}
function fetchMessagesForConversation(arg0: { conversationKey: string; count: number }): any {
throw new Error('Function not implemented.');
}

View File

@ -10,11 +10,7 @@ import { contextMenu } from 'react-contexify';
import { AttachmentType } from '../../../types/Attachment';
import { GroupNotification } from '../../conversation/GroupNotification';
import { GroupInvitation } from '../../conversation/GroupInvitation';
import {
ConversationType,
MessageModelProps,
SortedMessageModelProps,
} from '../../../state/ducks/conversations';
import { ReduxConversationType, SortedMessageModelProps } from '../../../state/ducks/conversations';
import { SessionLastSeenIndicator } from './SessionLastSeenIndicator';
import { ToastUtils } from '../../../session/utils';
import { TypingBubble } from '../../conversation/TypingBubble';
@ -36,7 +32,7 @@ interface Props {
selectedMessages: Array<string>;
conversationKey: string;
messagesProps: Array<SortedMessageModelProps>;
conversation: ConversationType;
conversation: ReduxConversationType;
ourPrimary: string;
messageContainerRef: React.RefObject<any>;
selectMessage: (messageId: string) => void;
@ -129,7 +125,7 @@ export class SessionMessagesList extends React.Component<Props, State> {
}
public render() {
const { conversationKey, conversation, messagesProps } = this.props;
const { conversationKey, conversation } = this.props;
const { showScrollButton } = this.state;
let displayedName = null;

View File

@ -11,7 +11,7 @@ import { HexKeyPair } from '../receiver/keypairs';
import { getSodium } from '../session/crypto';
import { PubKey } from '../session/types';
import { fromArrayBufferToBase64, fromBase64ToArrayBuffer } from '../session/utils/String';
import { ConversationType } from '../state/ducks/conversations';
import { ReduxConversationType } from '../state/ducks/conversations';
import { channels } from './channels';
import { channelsToMake as channelstoMakeOpenGroupV2 } from './opengroups';
@ -511,7 +511,7 @@ export async function removeAllClosedGroupEncryptionKeyPairs(
}
// Conversation
export async function saveConversation(data: ConversationType): Promise<void> {
export async function saveConversation(data: ReduxConversationType): Promise<void> {
const cleaned = _.omit(data, 'isOnline');
await channels.saveConversation(cleaned);
}
@ -524,7 +524,7 @@ export async function getConversationById(id: string): Promise<ConversationModel
return undefined;
}
export async function updateConversation(data: ConversationType): Promise<void> {
export async function updateConversation(data: ReduxConversationType): Promise<void> {
await channels.updateConversation(data);
}

View File

@ -2,9 +2,9 @@ import _ from 'lodash';
import { useEffect, useState } from 'react';
import { getConversationController } from '../session/conversations';
import { UserUtils } from '../session/utils';
import { ConversationType } from '../state/ducks/conversations';
import { ReduxConversationType } from '../state/ducks/conversations';
export function useMembersAvatars(conversation: ConversationType | undefined) {
export function useMembersAvatars(conversation: ReduxConversationType | undefined) {
const [membersAvatars, setMembersAvatars] = useState<
| Array<{
avatarPath: string | undefined;

View File

@ -24,9 +24,9 @@ import {
import { fromArrayBufferToBase64, fromBase64ToArrayBuffer } from '../session/utils/String';
import {
actions as conversationActions,
ConversationType as ReduxConversationType,
LastMessageStatusType,
MessageModelProps,
ReduxConversationType,
} from '../state/ducks/conversations';
import { ExpirationTimerUpdateMessage } from '../session/messages/outgoing/controlMessage/ExpirationTimerUpdateMessage';
import { TypingMessage } from '../session/messages/outgoing/controlMessage/TypingMessage';

View File

@ -168,7 +168,7 @@ export type LastMessageType = {
text: string | null;
};
export interface ConversationType {
export interface ReduxConversationType {
id: string;
name?: string;
profileName?: string;
@ -202,7 +202,7 @@ export interface ConversationType {
}
export type ConversationLookupType = {
[key: string]: ConversationType;
[key: string]: ReduxConversationType;
};
export type ConversationsStateType = {
@ -322,14 +322,14 @@ type ConversationAddedActionType = {
type: 'CONVERSATION_ADDED';
payload: {
id: string;
data: ConversationType;
data: ReduxConversationType;
};
};
type ConversationChangedActionType = {
type: 'CONVERSATION_CHANGED';
payload: {
id: string;
data: ConversationType;
data: ReduxConversationType;
};
};
type ConversationRemovedActionType = {
@ -425,7 +425,7 @@ export const actions = {
openConversationExternal,
};
function conversationAdded(id: string, data: ConversationType): ConversationAddedActionType {
function conversationAdded(id: string, data: ReduxConversationType): ConversationAddedActionType {
return {
type: 'CONVERSATION_ADDED',
payload: {
@ -434,7 +434,10 @@ function conversationAdded(id: string, data: ConversationType): ConversationAdde
},
};
}
function conversationChanged(id: string, data: ConversationType): ConversationChangedActionType {
function conversationChanged(
id: string,
data: ReduxConversationType
): ConversationChangedActionType {
return {
type: 'CONVERSATION_CHANGED',
payload: {

View File

@ -6,9 +6,9 @@ import { searchConversations, searchMessages } from '../../../ts/data/data';
import { makeLookup } from '../../util/makeLookup';
import {
ConversationType,
MessageExpiredActionType,
PropsForSearchResults,
ReduxConversationType,
RemoveAllConversationsActionType,
SelectedConversationChangedActionType,
} from './conversations';
@ -242,7 +242,7 @@ async function queryConversationsAndContacts(providedQuery: string, options: Sea
const { ourNumber, noteToSelf } = options;
const query = providedQuery.replace(/[+-.()]*/g, '');
const searchResults: Array<ConversationType> = await searchConversations(query);
const searchResults: Array<ReduxConversationType> = await searchConversations(query);
// Split into two groups - active conversations and items just from address book
let conversations: Array<string> = [];

View File

@ -4,8 +4,7 @@ import { StateType } from '../reducer';
import {
ConversationLookupType,
ConversationsStateType,
ConversationType,
MessageModelProps,
ReduxConversationType,
SortedMessageModelProps,
} from '../ducks/conversations';
@ -36,7 +35,7 @@ export const getSelectedConversationKey = createSelector(
export const getSelectedConversation = createSelector(
getConversations,
(state: ConversationsStateType): ConversationType | undefined => {
(state: ConversationsStateType): ReduxConversationType | undefined => {
return state.selectedConversation
? state.conversationLookup[state.selectedConversation]
: undefined;
@ -45,7 +44,7 @@ export const getSelectedConversation = createSelector(
export const getOurPrimaryConversation = createSelector(
getConversations,
(state: ConversationsStateType): ConversationType =>
(state: ConversationsStateType): ReduxConversationType =>
state.conversationLookup[window.storage.get('primaryDevicePubKey')]
);
@ -54,7 +53,10 @@ export const getMessagesOfSelectedConversation = createSelector(
(state: ConversationsStateType): Array<SortedMessageModelProps> => state.messages
);
function getConversationTitle(conversation: ConversationType, testingi18n?: LocalizerType): string {
function getConversationTitle(
conversation: ReduxConversationType,
testingi18n?: LocalizerType
): string {
if (conversation.name) {
return conversation.name;
}
@ -68,7 +70,7 @@ function getConversationTitle(conversation: ConversationType, testingi18n?: Loca
const collator = new Intl.Collator();
export const _getConversationComparator = (testingi18n?: LocalizerType) => {
return (left: ConversationType, right: ConversationType): number => {
return (left: ReduxConversationType, right: ReduxConversationType): number => {
const leftActiveAt = left.activeAt;
const rightActiveAt = right.activeAt;
if (leftActiveAt && !rightActiveAt) {
@ -91,18 +93,18 @@ export const getConversationComparator = createSelector(getIntl, _getConversatio
// export only because we use it in some of our tests
export const _getLeftPaneLists = (
lookup: ConversationLookupType,
comparator: (left: ConversationType, right: ConversationType) => number,
comparator: (left: ReduxConversationType, right: ReduxConversationType) => number,
selectedConversation?: string
): {
conversations: Array<ConversationType>;
contacts: Array<ConversationType>;
conversations: Array<ReduxConversationType>;
contacts: Array<ReduxConversationType>;
unreadCount: number;
} => {
const values = Object.values(lookup);
const sorted = values.sort(comparator);
const conversations: Array<ConversationType> = [];
const directConversations: Array<ConversationType> = [];
const conversations: Array<ReduxConversationType> = [];
const directConversations: Array<ReduxConversationType> = [];
let index = 0;
@ -172,11 +174,20 @@ export const getLeftPaneLists = createSelector(
export const getMe = createSelector(
[getConversationLookup, getOurNumber],
(lookup: ConversationLookupType, ourNumber: string): ConversationType => {
(lookup: ConversationLookupType, ourNumber: string): ReduxConversationType => {
return lookup[ourNumber];
}
);
export const getDirectContacts = createSelector(
getLeftPaneLists,
(state: {
conversations: Array<ReduxConversationType>;
contacts: Array<ReduxConversationType>;
unreadCount: number;
}) => state.contacts
);
export const getUnreadMessageCount = createSelector(getLeftPaneLists, (state): number => {
return state.unreadCount;
});