cleanedup redux action openConversationExternal
This commit is contained in:
parent
7f76ab274c
commit
ee4a0b9b1e
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
)}
|
||||
|
|
|
@ -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 />
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
|
|
@ -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)}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.');
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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> = [];
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue