diff --git a/app/soapbox/actions/chats.js b/app/soapbox/actions/chats.js
index 93938e3c3..d9b97ea50 100644
--- a/app/soapbox/actions/chats.js
+++ b/app/soapbox/actions/chats.js
@@ -111,6 +111,17 @@ export function toggleMainWindow() {
};
}
+export function fetchChat(chatId) {
+ return (dispatch, getState) => {
+ dispatch({ type: CHAT_FETCH_REQUEST, chatId });
+ return api(getState).get(`/api/v1/pleroma/chats/${chatId}`).then(({ data }) => {
+ dispatch({ type: CHAT_FETCH_SUCCESS, chat: data });
+ }).catch(error => {
+ dispatch({ type: CHAT_FETCH_FAIL, chatId, error });
+ });
+ };
+}
+
export function startChat(accountId) {
return (dispatch, getState) => {
dispatch({ type: CHAT_FETCH_REQUEST, accountId });
diff --git a/app/soapbox/features/chats/chat_room.js b/app/soapbox/features/chats/chat_room.js
index fc17f9c2e..b10ff5470 100644
--- a/app/soapbox/features/chats/chat_room.js
+++ b/app/soapbox/features/chats/chat_room.js
@@ -4,104 +4,51 @@ import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { injectIntl } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
-import {
- fetchChatMessages,
- sendChatMessage,
- markChatRead,
-} from 'soapbox/actions/chats';
-import { List as ImmutableList, OrderedSet as ImmutableOrderedSet } from 'immutable';
-import ChatMessageList from './components/chat_message_list';
+import { fetchChat } from 'soapbox/actions/chats';
+import ChatBox from './components/chat_box';
import Column from 'soapbox/features/ui/components/column';
const mapStateToProps = (state, { params }) => ({
me: state.get('me'),
chat: state.getIn(['chats', params.chatId]),
- chatMessageIds: state.getIn(['chat_message_lists', params.chatId], ImmutableOrderedSet()),
});
export default @connect(mapStateToProps)
@injectIntl
-class ChatWindow extends ImmutablePureComponent {
+class ChatRoom extends ImmutablePureComponent {
static propTypes = {
dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
- chatMessageIds: ImmutablePropTypes.orderedSet,
chat: ImmutablePropTypes.map,
me: PropTypes.node,
}
- static defaultProps = {
- chatMessages: ImmutableList(),
- }
-
- state = {
- content: '',
- }
-
- handleKeyDown = (chatId) => {
- return (e) => {
- if (e.key === 'Enter') {
- this.props.dispatch(sendChatMessage(chatId, this.state));
- this.setState({ content: '' });
- e.preventDefault();
- }
- };
- }
-
- handleContentChange = (e) => {
- this.setState({ content: e.target.value });
- }
-
- handleReadChat = (e) => {
- const { dispatch, chat } = this.props;
- dispatch(markChatRead(chat.get('id')));
- }
+ handleInputRef = (el) => {
+ this.inputElem = el;
+ this.focusInput();
+ };
focusInput = () => {
if (!this.inputElem) return;
this.inputElem.focus();
}
- setInputRef = (el) => {
- this.inputElem = el;
- this.focusInput();
- };
-
componentDidMount() {
- const { dispatch, chatMessages, params } = this.props;
- if (chatMessages && chatMessages.count() < 1)
- dispatch(fetchChatMessages(params.chatId));
- }
-
- componentDidUpdate(prevProps) {
- const markReadConditions = [
- () => this.props.chat !== undefined,
- () => document.activeElement === this.inputElem,
- () => this.props.chat.get('unread') > 0,
- ];
-
- if (markReadConditions.every(c => c() === true))
- this.handleReadChat();
+ const { dispatch, params } = this.props;
+ dispatch(fetchChat(params.chatId));
}
render() {
- const { chatMessageIds, chat } = this.props;
+ const { chat } = this.props;
if (!chat) return null;
return (
-
-
-
-
+
);
}
diff --git a/app/soapbox/features/chats/components/chat_box.js b/app/soapbox/features/chats/components/chat_box.js
new file mode 100644
index 000000000..0f1de7dbb
--- /dev/null
+++ b/app/soapbox/features/chats/components/chat_box.js
@@ -0,0 +1,108 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import { injectIntl, defineMessages } from 'react-intl';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import {
+ fetchChatMessages,
+ sendChatMessage,
+ markChatRead,
+} from 'soapbox/actions/chats';
+import { OrderedSet as ImmutableOrderedSet } from 'immutable';
+import ChatMessageList from './chat_message_list';
+
+const messages = defineMessages({
+ placeholder: { id: 'chat_box.input.placeholder', defaultMessage: 'Send a messageā¦' },
+});
+
+const mapStateToProps = (state, { chatId }) => ({
+ me: state.get('me'),
+ chat: state.getIn(['chats', chatId]),
+ chatMessageIds: state.getIn(['chat_message_lists', chatId], ImmutableOrderedSet()),
+});
+
+export default @connect(mapStateToProps)
+@injectIntl
+class ChatBox extends ImmutablePureComponent {
+
+ static propTypes = {
+ dispatch: PropTypes.func.isRequired,
+ intl: PropTypes.object.isRequired,
+ chatId: PropTypes.string.isRequired,
+ chatMessageIds: ImmutablePropTypes.orderedSet,
+ chat: ImmutablePropTypes.map,
+ onSetInputRef: PropTypes.func,
+ me: PropTypes.node,
+ }
+
+ state = {
+ content: '',
+ }
+
+ handleKeyDown = (e) => {
+ const { chatId } = this.props;
+ if (e.key === 'Enter') {
+ this.props.dispatch(sendChatMessage(chatId, this.state));
+ this.setState({ content: '' });
+ e.preventDefault();
+ }
+ }
+
+ handleContentChange = (e) => {
+ this.setState({ content: e.target.value });
+ }
+
+ markRead = () => {
+ const { dispatch, chatId } = this.props;
+ dispatch(markChatRead(chatId));
+ }
+
+ handleHover = () => {
+ this.markRead();
+ }
+
+ setInputRef = (el) => {
+ const { onSetInputRef } = this.props;
+ this.inputElem = el;
+ onSetInputRef(el);
+ };
+
+ componentDidMount() {
+ const { dispatch, chatId } = this.props;
+ dispatch(fetchChatMessages(chatId));
+ }
+
+ componentDidUpdate(prevProps) {
+ const markReadConditions = [
+ () => this.props.chat !== undefined,
+ () => document.activeElement === this.inputElem,
+ () => this.props.chat.get('unread') > 0,
+ ];
+
+ if (markReadConditions.every(c => c() === true))
+ this.markRead();
+ }
+
+ render() {
+ const { chatMessageIds, intl } = this.props;
+ if (!chatMessageIds) return null;
+
+ return (
+
+ );
+ }
+
+}
diff --git a/app/soapbox/features/chats/components/chat_window.js b/app/soapbox/features/chats/components/chat_window.js
index 056a33aa0..5fea70cd6 100644
--- a/app/soapbox/features/chats/components/chat_window.js
+++ b/app/soapbox/features/chats/components/chat_window.js
@@ -10,18 +10,13 @@ import IconButton from 'soapbox/components/icon_button';
import {
closeChat,
toggleChat,
- fetchChatMessages,
- sendChatMessage,
- markChatRead,
} from 'soapbox/actions/chats';
-import { List as ImmutableList, OrderedSet as ImmutableOrderedSet } from 'immutable';
-import ChatMessageList from './chat_message_list';
+import ChatBox from './chat_box';
import { shortNumberFormat } from 'soapbox/utils/numbers';
const mapStateToProps = (state, { pane }) => ({
me: state.get('me'),
chat: state.getIn(['chats', pane.get('chat_id')]),
- chatMessageIds: state.getIn(['chat_message_lists', pane.get('chat_id')], ImmutableOrderedSet()),
});
export default @connect(mapStateToProps)
@@ -33,15 +28,10 @@ class ChatWindow extends ImmutablePureComponent {
intl: PropTypes.object.isRequired,
pane: ImmutablePropTypes.map.isRequired,
idx: PropTypes.number,
- chatMessageIds: ImmutablePropTypes.orderedSet,
chat: ImmutablePropTypes.map,
me: PropTypes.node,
}
- static defaultProps = {
- chatMessages: ImmutableList(),
- }
-
state = {
content: '',
}
@@ -58,65 +48,30 @@ class ChatWindow extends ImmutablePureComponent {
};
}
- handleKeyDown = (chatId) => {
- return (e) => {
- if (e.key === 'Enter') {
- this.props.dispatch(sendChatMessage(chatId, this.state));
- this.setState({ content: '' });
- e.preventDefault();
- }
- };
- }
-
handleContentChange = (e) => {
this.setState({ content: e.target.value });
}
- handleHover = () => {
- if (this.props.pane.get('state') === 'open') this.markRead();
- }
-
- markRead = () => {
- const { dispatch, chat } = this.props;
- dispatch(markChatRead(chat.get('id')));
- }
+ handleInputRef = (el) => {
+ this.inputElem = el;
+ this.focusInput();
+ };
focusInput = () => {
if (!this.inputElem) return;
this.inputElem.focus();
}
- setInputRef = (el) => {
- const { pane } = this.props;
- this.inputElem = el;
- if (pane.get('state') === 'open') this.focusInput();
- };
-
- componentDidMount() {
- const { dispatch, pane, chatMessages } = this.props;
- if (chatMessages && chatMessages.count() < 1)
- dispatch(fetchChatMessages(pane.get('chat_id')));
- }
-
componentDidUpdate(prevProps) {
const oldState = prevProps.pane.get('state');
const newState = this.props.pane.get('state');
if (oldState !== newState && newState === 'open')
this.focusInput();
-
- const markReadConditions = [
- () => this.props.chat !== undefined,
- () => document.activeElement === this.inputElem,
- () => this.props.chat.get('unread') > 0,
- ];
-
- if (markReadConditions.every(c => c() === true))
- this.markRead();
}
render() {
- const { pane, idx, chatMessageIds, chat } = this.props;
+ const { pane, idx, chat } = this.props;
const account = pane.getIn(['chat', 'account']);
if (!chat || !account) return null;
@@ -124,7 +79,7 @@ class ChatWindow extends ImmutablePureComponent {
const unreadCount = chat.get('unread');
return (
-
+
{unreadCount > 0
? {shortNumberFormat(unreadCount)}
@@ -138,17 +93,10 @@ class ChatWindow extends ImmutablePureComponent {
);
diff --git a/app/soapbox/features/chats/index.js b/app/soapbox/features/chats/index.js
index bfb605f86..1420325f1 100644
--- a/app/soapbox/features/chats/index.js
+++ b/app/soapbox/features/chats/index.js
@@ -13,7 +13,6 @@ export default @injectIntl
class ChatIndex extends React.PureComponent {
static propTypes = {
- dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
};
diff --git a/app/soapbox/reducers/chat_messages.js b/app/soapbox/reducers/chat_messages.js
index 55f758afe..74d83ef79 100644
--- a/app/soapbox/reducers/chat_messages.js
+++ b/app/soapbox/reducers/chat_messages.js
@@ -32,6 +32,7 @@ export default function chatMessages(state = initialState, action) {
chat_id: action.chatId,
account_id: action.me,
content: action.params.content,
+ created_at: (new Date()).toISOString(),
pending: true,
}));
case CHATS_FETCH_SUCCESS:
diff --git a/app/styles/chats.scss b/app/styles/chats.scss
index b4e00acc8..5fdd76e98 100644
--- a/app/styles/chats.scss
+++ b/app/styles/chats.scss
@@ -86,23 +86,12 @@
flex: 1;
flex-direction: column;
overflow: hidden;
- }
- &__actions {
- background: var(--foreground-color);
- margin-top: auto;
- padding: 6px;
-
- textarea {
- width: 100%;
- margin: 0;
- box-sizing: border-box;
- padding: 6px;
- background: var(--background-color);
- border: 0;
- border-radius: 6px;
- color: var(--primary-text-color);
- font-size: 15px;
+ .chat-box {
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+ overflow: hidden;
}
}
}
@@ -166,3 +155,23 @@
bottom: auto;
}
}
+
+.chat-box {
+ &__actions {
+ background: var(--foreground-color);
+ margin-top: auto;
+ padding: 6px;
+
+ textarea {
+ width: 100%;
+ margin: 0;
+ box-sizing: border-box;
+ padding: 6px;
+ background: var(--background-color);
+ border: 0;
+ border-radius: 6px;
+ color: var(--primary-text-color);
+ font-size: 15px;
+ }
+ }
+}