sforkowany z mirror/soapbox
Merge branch 'chat-fixes' into 'develop'
Chat fixes Closes #382, #384, #367, and #375 See merge request soapbox-pub/soapbox-fe!203better-thread-display
commit
48083e7f86
|
@ -6,18 +6,20 @@ import { injectIntl } from 'react-intl';
|
|||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import Avatar from 'soapbox/components/avatar';
|
||||
import { acctFull } from 'soapbox/utils/accounts';
|
||||
import { fetchChat } from 'soapbox/actions/chats';
|
||||
import { fetchChat, markChatRead } from 'soapbox/actions/chats';
|
||||
import ChatBox from './components/chat_box';
|
||||
import Column from 'soapbox/components/column';
|
||||
import ColumnBackButton from 'soapbox/components/column_back_button';
|
||||
import { Map as ImmutableMap } from 'immutable';
|
||||
import { makeGetChat } from 'soapbox/selectors';
|
||||
|
||||
const mapStateToProps = (state, { params }) => {
|
||||
const getChat = makeGetChat();
|
||||
const chat = state.getIn(['chats', params.chatId], ImmutableMap()).toJS();
|
||||
|
||||
return {
|
||||
me: state.get('me'),
|
||||
chat: getChat(state, { id: params.chatId }),
|
||||
chat: getChat(state, chat),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -42,9 +44,26 @@ class ChatRoom extends ImmutablePureComponent {
|
|||
this.inputElem.focus();
|
||||
}
|
||||
|
||||
markRead = () => {
|
||||
const { dispatch, chat } = this.props;
|
||||
if (!chat) return;
|
||||
dispatch(markChatRead(chat.get('id')));
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { dispatch, params } = this.props;
|
||||
dispatch(fetchChat(params.chatId));
|
||||
this.markRead();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const markReadConditions = [
|
||||
() => this.props.chat !== undefined,
|
||||
() => this.props.chat.get('unread') > 0,
|
||||
];
|
||||
|
||||
if (markReadConditions.every(c => c() === true))
|
||||
this.markRead();
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -40,11 +40,24 @@ class ChatBox extends ImmutablePureComponent {
|
|||
content: '',
|
||||
}
|
||||
|
||||
handleKeyDown = (e) => {
|
||||
sendMessage = () => {
|
||||
const { chatId } = this.props;
|
||||
if (e.key === 'Enter') {
|
||||
this.props.dispatch(sendChatMessage(chatId, this.state));
|
||||
this.setState({ content: '' });
|
||||
if (this.state.content.length < 1) return;
|
||||
this.props.dispatch(sendChatMessage(chatId, this.state));
|
||||
this.setState({ content: '' });
|
||||
}
|
||||
|
||||
insertLine = () => {
|
||||
const { content } = this.state;
|
||||
this.setState({ content: content + '\n' });
|
||||
}
|
||||
|
||||
handleKeyDown = (e) => {
|
||||
if (e.key === 'Enter' && e.shiftKey) {
|
||||
this.insertLine();
|
||||
e.preventDefault();
|
||||
} else if (e.key === 'Enter') {
|
||||
this.sendMessage();
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ import { connect } from 'react-redux';
|
|||
import PropTypes from 'prop-types';
|
||||
import { injectIntl } from 'react-intl';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { fetchChats } from 'soapbox/actions/chats';
|
||||
import Chat from './chat';
|
||||
import { makeGetChat } from 'soapbox/selectors';
|
||||
|
||||
|
@ -42,10 +41,6 @@ class ChatList extends ImmutablePureComponent {
|
|||
emptyMessage: PropTypes.node,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dispatch(fetchChats());
|
||||
}
|
||||
|
||||
render() {
|
||||
const { chats, emptyMessage } = this.props;
|
||||
|
||||
|
|
|
@ -4,9 +4,14 @@ import PropTypes from 'prop-types';
|
|||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import { injectIntl } from 'react-intl';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { List as ImmutableList } from 'immutable';
|
||||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
||||
import emojify from 'soapbox/features/emoji/emoji';
|
||||
import classNames from 'classnames';
|
||||
import { escape } from 'lodash';
|
||||
|
||||
const makeEmojiMap = record => record.get('emojis', ImmutableList()).reduce((map, emoji) => {
|
||||
return map.set(`:${emoji.get('shortcode')}:`, emoji);
|
||||
}, ImmutableMap());
|
||||
|
||||
const mapStateToProps = (state, { chatMessageIds }) => ({
|
||||
me: state.get('me'),
|
||||
|
@ -72,6 +77,18 @@ class ChatMessageList extends ImmutablePureComponent {
|
|||
this.scrollToBottom();
|
||||
}
|
||||
|
||||
parsePendingContent = content => {
|
||||
return escape(content).replace(/(?:\r\n|\r|\n)/g, '<br>');
|
||||
}
|
||||
|
||||
parseContent = chatMessage => {
|
||||
const content = chatMessage.get('content') || '';
|
||||
const pending = chatMessage.get('pending', false);
|
||||
const formatted = pending ? this.parsePendingContent(content) : content;
|
||||
const emojiMap = makeEmojiMap(chatMessage);
|
||||
return emojify(formatted, emojiMap.toJS());
|
||||
}
|
||||
|
||||
render() {
|
||||
const { chatMessages, me } = this.props;
|
||||
|
||||
|
@ -88,7 +105,7 @@ class ChatMessageList extends ImmutablePureComponent {
|
|||
<span
|
||||
title={this.getFormattedTimestamp(chatMessage)}
|
||||
className='chat-message__bubble'
|
||||
dangerouslySetInnerHTML={{ __html: emojify(chatMessage.get('content') || '') }}
|
||||
dangerouslySetInnerHTML={{ __html: this.parseContent(chatMessage) }}
|
||||
ref={this.setRef}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -18,6 +18,7 @@ import { expandHomeTimeline } from '../../actions/timelines';
|
|||
import { expandNotifications } from '../../actions/notifications';
|
||||
import { fetchReports } from '../../actions/admin';
|
||||
import { fetchFilters } from '../../actions/filters';
|
||||
import { fetchChats } from 'soapbox/actions/chats';
|
||||
import { clearHeight } from '../../actions/height_cache';
|
||||
import { openModal } from '../../actions/modal';
|
||||
import { WrappedRoute } from './util/react_router_helpers';
|
||||
|
@ -433,6 +434,7 @@ class UI extends React.PureComponent {
|
|||
if (account) {
|
||||
this.props.dispatch(expandHomeTimeline());
|
||||
this.props.dispatch(expandNotifications());
|
||||
this.props.dispatch(fetchChats());
|
||||
// this.props.dispatch(fetchGroups('member'));
|
||||
if (isStaff(account))
|
||||
this.props.dispatch(fetchReports({ state: 'open' }));
|
||||
|
|
|
@ -113,6 +113,8 @@
|
|||
background-color: var(--background-color);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
overflow-wrap: break-word;
|
||||
white-space: break-spaces;
|
||||
|
||||
a {
|
||||
color: var(--brand-color--hicontrast);
|
||||
|
|
Ładowanie…
Reference in New Issue