diff --git a/app/soapbox/actions/chats.js b/app/soapbox/actions/chats.js index 419608e2c..35543ca8c 100644 --- a/app/soapbox/actions/chats.js +++ b/app/soapbox/actions/chats.js @@ -7,6 +7,10 @@ export const CHATS_FETCH_REQUEST = 'CHATS_FETCH_REQUEST'; export const CHATS_FETCH_SUCCESS = 'CHATS_FETCH_SUCCESS'; export const CHATS_FETCH_FAIL = 'CHATS_FETCH_FAIL'; +export const CHAT_MESSAGES_FETCH_REQUEST = 'CHAT_MESSAGES_FETCH_REQUEST'; +export const CHAT_MESSAGES_FETCH_SUCCESS = 'CHAT_MESSAGES_FETCH_SUCCESS'; +export const CHAT_MESSAGES_FETCH_FAIL = 'CHAT_MESSAGES_FETCH_FAIL'; + export function fetchChats() { return (dispatch, getState) => { dispatch({ type: CHATS_FETCH_REQUEST }); @@ -19,6 +23,17 @@ export function fetchChats() { }; } +export function fetchChatMessages(chatId) { + return (dispatch, getState) => { + dispatch({ type: CHAT_MESSAGES_FETCH_REQUEST, chatId }); + return api(getState).get(`/api/v1/pleroma/chats/${chatId}/messages`).then(({ data }) => { + dispatch({ type: CHAT_MESSAGES_FETCH_SUCCESS, chatId, data }); + }).catch(error => { + dispatch({ type: CHAT_MESSAGES_FETCH_FAIL, chatId, error }); + }); + }; +} + export function openChat(chatId) { return (dispatch, getState) => { const panes = getSettings(getState()).getIn(['chats', 'panes']); diff --git a/app/soapbox/features/chats/components/chat_panes.js b/app/soapbox/features/chats/components/chat_panes.js index 58ab6d404..8a9e28a04 100644 --- a/app/soapbox/features/chats/components/chat_panes.js +++ b/app/soapbox/features/chats/components/chat_panes.js @@ -8,15 +8,8 @@ import { getSettings } from 'soapbox/actions/settings'; import ChatList from './chat_list'; import { FormattedMessage } from 'react-intl'; import { makeGetChat } from 'soapbox/selectors'; -import Avatar from 'soapbox/components/avatar'; -import { acctFull } from 'soapbox/utils/accounts'; -import { - openChat, - closeChat, - toggleChat, - toggleMainWindow, -} from 'soapbox/actions/chats'; -import IconButton from 'soapbox/components/icon_button'; +import { openChat, toggleMainWindow } from 'soapbox/actions/chats'; +import ChatWindow from './chat_window'; const addChatsToPanes = (state, panesData) => { const getChat = makeGetChat(); @@ -52,56 +45,10 @@ class ChatPanes extends ImmutablePureComponent { // TODO: Focus chat input } - handleChatClose = (chatId) => { - return (e) => { - this.props.dispatch(closeChat(chatId)); - }; - } - - handleChatToggle = (chatId) => { - return (e) => { - this.props.dispatch(toggleChat(chatId)); - }; - } - handleMainWindowToggle = () => { this.props.dispatch(toggleMainWindow()); } - renderChatPane = (pane, i) => { - const chat = pane.get('chat'); - const account = pane.getIn(['chat', 'account']); - if (!chat || !account) return null; - - const right = (285 * (i + 1)) + 20; - - return ( -
-
- - -
- -
-
-
-
TODO: Show the chat messages
-
- -
-
-
- ); - } - - renderChatPanes = (panes) => ( - panes.map((pane, i) => - this.renderChatPane(pane, i) - ) - ) - render() { const { panesData } = this.props; const panes = panesData.get('panes'); @@ -119,7 +66,9 @@ class ChatPanes extends ImmutablePureComponent { - {this.renderChatPanes(panes)} + {panes.map((pane, i) => + + )} ); } diff --git a/app/soapbox/features/chats/components/chat_window.js b/app/soapbox/features/chats/components/chat_window.js new file mode 100644 index 000000000..7eb6be45a --- /dev/null +++ b/app/soapbox/features/chats/components/chat_window.js @@ -0,0 +1,84 @@ +import React from 'react'; +import { connect } from 'react-redux'; +import PropTypes from 'prop-types'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +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 IconButton from 'soapbox/components/icon_button'; +import { closeChat, toggleChat, fetchChatMessages } from 'soapbox/actions/chats'; +import { List as ImmutableList } from 'immutable'; + +const mapStateToProps = (state, { pane }) => ({ + chatMessages: state.getIn(['chat_messages', pane.get('chat_id')], ImmutableList()), +}); + +export default @connect(mapStateToProps) +@injectIntl +class ChatWindow extends ImmutablePureComponent { + + static propTypes = { + dispatch: PropTypes.func.isRequired, + intl: PropTypes.object.isRequired, + pane: ImmutablePropTypes.map.isRequired, + idx: PropTypes.number, + chatMessages: ImmutablePropTypes.list, + } + + static defaultProps = { + chatMessages: ImmutableList(), + } + + handleChatClose = (chatId) => { + return (e) => { + this.props.dispatch(closeChat(chatId)); + }; + } + + handleChatToggle = (chatId) => { + return (e) => { + this.props.dispatch(toggleChat(chatId)); + }; + } + + componentDidMount() { + const { dispatch, pane, chatMessages } = this.props; + if (chatMessages && chatMessages.count() < 1) + dispatch(fetchChatMessages(pane.get('chat_id'))); + } + + render() { + const { pane, idx, chatMessages } = this.props; + const chat = pane.get('chat'); + const account = pane.getIn(['chat', 'account']); + if (!chat || !account) return null; + + const right = (285 * (idx + 1)) + 20; + + return ( +
+
+ + +
+ +
+
+
+
+ {chatMessages.map(chatMessage => +
{chatMessage.get('content')}
+ )} +
+
+ +
+
+
+ ); + } + +} diff --git a/app/soapbox/reducers/chat_messages.js b/app/soapbox/reducers/chat_messages.js new file mode 100644 index 000000000..fe3ccbfe9 --- /dev/null +++ b/app/soapbox/reducers/chat_messages.js @@ -0,0 +1,13 @@ +import { CHAT_MESSAGES_FETCH_SUCCESS } from 'soapbox/actions/chats'; +import { Map as ImmutableMap, fromJS } from 'immutable'; + +const initialState = ImmutableMap(); + +export default function chatMessages(state = initialState, action) { + switch(action.type) { + case CHAT_MESSAGES_FETCH_SUCCESS: + return state.set(action.chatId, fromJS(action.data)); + default: + return state; + } +}; diff --git a/app/soapbox/reducers/chats.js b/app/soapbox/reducers/chats.js index aeca5958c..244c76b85 100644 --- a/app/soapbox/reducers/chats.js +++ b/app/soapbox/reducers/chats.js @@ -8,7 +8,7 @@ const importChats = (state, chats) => const initialState = ImmutableMap(); -export default function admin(state = initialState, action) { +export default function chats(state = initialState, action) { switch(action.type) { case CHAT_IMPORT: return importChat(state, action.chat); diff --git a/app/soapbox/reducers/index.js b/app/soapbox/reducers/index.js index 90cd6af62..320b78036 100644 --- a/app/soapbox/reducers/index.js +++ b/app/soapbox/reducers/index.js @@ -44,6 +44,7 @@ import me from './me'; import auth from './auth'; import admin from './admin'; import chats from './chats'; +import chat_messages from './chat_messages'; const reducers = { dropdown_menu, @@ -91,6 +92,7 @@ const reducers = { auth, admin, chats, + chat_messages, }; export default combineReducers(reducers);