Chats: add account search

profile-avatar-switcher
Alex Gleason 2021-10-14 12:23:51 -05:00
rodzic 3fb9ebc553
commit f70791004b
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 7211D1F99744FBB7
8 zmienionych plików z 70 dodań i 19 usunięć

Wyświetl plik

@ -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));

Wyświetl plik

@ -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) {

Wyświetl plik

@ -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) {

Wyświetl plik

@ -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 && (
<>
<ChatList
onClickChat={this.handleClickChat} onClickChat={this.handleClickChat}
emptyMessage={<FormattedMessage id='chat_panels.main_window.empty' defaultMessage="No chats found. To start a chat, visit a user's profile." />} 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>
); );

Wyświetl plik

@ -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}

Wyświetl plik

@ -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) {

Wyświetl plik

@ -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) => {

Wyświetl plik

@ -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);