sforkowany z mirror/soapbox
Chats: add account search
rodzic
3fb9ebc553
commit
f70791004b
|
@ -167,13 +167,13 @@ export function deleteChatMessage(chatId, messageId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Start a chat and launch it in the UI */
|
/** Start a chat and launch it in the UI */
|
||||||
export function launchChat(account, router) {
|
export function launchChat(accountId, router, forceNavigate = false) {
|
||||||
const isMobile = width => width <= 1190;
|
const isMobile = width => width <= 1190;
|
||||||
|
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
// TODO: make this faster
|
// TODO: make this faster
|
||||||
return dispatch(startChat(account.get('id'))).then(chat => {
|
return dispatch(startChat(accountId)).then(chat => {
|
||||||
if (isMobile(window.innerWidth)) {
|
if (forceNavigate || isMobile(window.innerWidth)) {
|
||||||
router.push(`/chats/${chat.id}`);
|
router.push(`/chats/${chat.id}`);
|
||||||
} else {
|
} else {
|
||||||
dispatch(openChat(chat.id));
|
dispatch(openChat(chat.id));
|
||||||
|
|
|
@ -153,7 +153,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
},
|
},
|
||||||
|
|
||||||
onChat(account, router) {
|
onChat(account, router) {
|
||||||
dispatch(launchChat(account, router));
|
dispatch(launchChat(account.get('id'), router));
|
||||||
},
|
},
|
||||||
|
|
||||||
onMention(account, router) {
|
onMention(account, router) {
|
||||||
|
|
|
@ -162,7 +162,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
},
|
},
|
||||||
|
|
||||||
onChat(account, router) {
|
onChat(account, router) {
|
||||||
dispatch(launchChat(account, router));
|
dispatch(launchChat(account.get('id'), router));
|
||||||
},
|
},
|
||||||
|
|
||||||
onDeactivateUser(account) {
|
onDeactivateUser(account) {
|
||||||
|
|
|
@ -6,12 +6,18 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import { getSettings } from 'soapbox/actions/settings';
|
import { getSettings } from 'soapbox/actions/settings';
|
||||||
import ChatList from './chat_list';
|
import ChatList from './chat_list';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import { openChat, toggleMainWindow } from 'soapbox/actions/chats';
|
import { openChat, launchChat, toggleMainWindow } from 'soapbox/actions/chats';
|
||||||
import ChatWindow from './chat_window';
|
import ChatWindow from './chat_window';
|
||||||
import { shortNumberFormat } from 'soapbox/utils/numbers';
|
import { shortNumberFormat } from 'soapbox/utils/numbers';
|
||||||
import AudioToggle from 'soapbox/features/chats/components/audio_toggle';
|
import AudioToggle from 'soapbox/features/chats/components/audio_toggle';
|
||||||
import { List as ImmutableList } from 'immutable';
|
import { List as ImmutableList } from 'immutable';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
|
import AccountSearch from 'soapbox/components/account_search';
|
||||||
|
import { injectIntl, defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
searchPlaceholder: { id: 'chats.search_placeholder', defaultMessage: 'Start a chat with…' },
|
||||||
|
});
|
||||||
|
|
||||||
const getChatsUnreadCount = state => {
|
const getChatsUnreadCount = state => {
|
||||||
const chats = state.get('chats');
|
const chats = state.get('chats');
|
||||||
|
@ -43,9 +49,15 @@ const makeMapStateToProps = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default @connect(makeMapStateToProps)
|
export default @connect(makeMapStateToProps)
|
||||||
|
@injectIntl
|
||||||
class ChatPanes extends ImmutablePureComponent {
|
class ChatPanes extends ImmutablePureComponent {
|
||||||
|
|
||||||
|
static contextTypes = {
|
||||||
|
router: PropTypes.object,
|
||||||
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
intl: PropTypes.object.isRequired,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
mainWindowState: PropTypes.string,
|
mainWindowState: PropTypes.string,
|
||||||
panes: ImmutablePropTypes.list,
|
panes: ImmutablePropTypes.list,
|
||||||
|
@ -55,12 +67,16 @@ class ChatPanes extends ImmutablePureComponent {
|
||||||
this.props.dispatch(openChat(chat.get('id')));
|
this.props.dispatch(openChat(chat.get('id')));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleSuggestion = accountId => {
|
||||||
|
this.props.dispatch(launchChat(accountId, this.context.router.history));
|
||||||
|
}
|
||||||
|
|
||||||
handleMainWindowToggle = () => {
|
handleMainWindowToggle = () => {
|
||||||
this.props.dispatch(toggleMainWindow());
|
this.props.dispatch(toggleMainWindow());
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { panes, mainWindowState, unreadCount } = this.props;
|
const { intl, panes, mainWindowState, unreadCount } = this.props;
|
||||||
const open = mainWindowState === 'open';
|
const open = mainWindowState === 'open';
|
||||||
|
|
||||||
const mainWindowPane = (
|
const mainWindowPane = (
|
||||||
|
@ -73,10 +89,18 @@ class ChatPanes extends ImmutablePureComponent {
|
||||||
<AudioToggle />
|
<AudioToggle />
|
||||||
</div>
|
</div>
|
||||||
<div className='pane__content'>
|
<div className='pane__content'>
|
||||||
{open && <ChatList
|
{open && (
|
||||||
onClickChat={this.handleClickChat}
|
<>
|
||||||
emptyMessage={<FormattedMessage id='chat_panels.main_window.empty' defaultMessage="No chats found. To start a chat, visit a user's profile." />}
|
<ChatList
|
||||||
/>}
|
onClickChat={this.handleClickChat}
|
||||||
|
emptyMessage={<FormattedMessage id='chat_panels.main_window.empty' defaultMessage="No chats found. To start a chat, visit a user's profile." />}
|
||||||
|
/>
|
||||||
|
<AccountSearch
|
||||||
|
placeholder={intl.formatMessage(messages.searchPlaceholder)}
|
||||||
|
onSelected={this.handleSuggestion}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,26 +1,36 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
import Column from '../../components/column';
|
import Column from '../../components/column';
|
||||||
import ColumnHeader from '../../components/column_header';
|
import ColumnHeader from '../../components/column_header';
|
||||||
|
import { launchChat } from 'soapbox/actions/chats';
|
||||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||||
import ChatList from './components/chat_list';
|
import ChatList from './components/chat_list';
|
||||||
import AudioToggle from 'soapbox/features/chats/components/audio_toggle';
|
import AudioToggle from 'soapbox/features/chats/components/audio_toggle';
|
||||||
|
import AccountSearch from 'soapbox/components/account_search';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
title: { id: 'column.chats', defaultMessage: 'Chats' },
|
title: { id: 'column.chats', defaultMessage: 'Chats' },
|
||||||
|
searchPlaceholder: { id: 'chats.search_placeholder', defaultMessage: 'Start a chat with…' },
|
||||||
});
|
});
|
||||||
|
|
||||||
export default @injectIntl
|
export default @connect()
|
||||||
|
@injectIntl
|
||||||
class ChatIndex extends React.PureComponent {
|
class ChatIndex extends React.PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
|
||||||
intl: PropTypes.object.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
router: PropTypes.object,
|
router: PropTypes.object,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
intl: PropTypes.object.isRequired,
|
||||||
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
handleSuggestion = accountId => {
|
||||||
|
this.props.dispatch(launchChat(accountId, this.context.router.history, true));
|
||||||
|
}
|
||||||
|
|
||||||
handleClickChat = (chat) => {
|
handleClickChat = (chat) => {
|
||||||
this.context.router.history.push(`/chats/${chat.get('id')}`);
|
this.context.router.history.push(`/chats/${chat.get('id')}`);
|
||||||
}
|
}
|
||||||
|
@ -34,7 +44,15 @@ class ChatIndex extends React.PureComponent {
|
||||||
icon='comment'
|
icon='comment'
|
||||||
title={intl.formatMessage(messages.title)}
|
title={intl.formatMessage(messages.title)}
|
||||||
/>
|
/>
|
||||||
<div className='column__switch'><AudioToggle /></div>
|
|
||||||
|
<div className='column__switch'>
|
||||||
|
<AudioToggle />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<AccountSearch
|
||||||
|
placeholder={intl.formatMessage(messages.searchPlaceholder)}
|
||||||
|
onSelected={this.handleSuggestion}
|
||||||
|
/>
|
||||||
|
|
||||||
<ChatList
|
<ChatList
|
||||||
onClickChat={this.handleClickChat}
|
onClickChat={this.handleClickChat}
|
||||||
|
|
|
@ -143,7 +143,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
},
|
},
|
||||||
|
|
||||||
onChat(account, router) {
|
onChat(account, router) {
|
||||||
dispatch(launchChat(account, router));
|
dispatch(launchChat(account.get('id'), router));
|
||||||
},
|
},
|
||||||
|
|
||||||
onMention(account, router) {
|
onMention(account, router) {
|
||||||
|
|
|
@ -257,7 +257,7 @@ class Status extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChatClick = (account, router) => {
|
handleChatClick = (account, router) => {
|
||||||
this.props.dispatch(launchChat(account, router));
|
this.props.dispatch(launchChat(account.get('id'), router));
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMentionClick = (account, router) => {
|
handleMentionClick = (account, router) => {
|
||||||
|
|
|
@ -24,6 +24,15 @@
|
||||||
height: 31px;
|
height: 31px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search--account {
|
||||||
|
border-top: 1px solid hsla(var(--primary-text-color_hsl), 0.2);
|
||||||
|
|
||||||
|
.autosuggest-textarea__suggestions {
|
||||||
|
top: auto;
|
||||||
|
bottom: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&__header {
|
&__header {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background: var(--brand-color);
|
background: var(--brand-color);
|
||||||
|
|
Ładowanie…
Reference in New Issue