From 2dd3b39e7e9d984d0a25fe995ea198403b385ff4 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 22 Sep 2020 14:21:07 -0500 Subject: [PATCH 1/5] Chats: add label to send button --- app/soapbox/features/chats/components/chat_box.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/soapbox/features/chats/components/chat_box.js b/app/soapbox/features/chats/components/chat_box.js index cded7fd70..2a0b72e89 100644 --- a/app/soapbox/features/chats/components/chat_box.js +++ b/app/soapbox/features/chats/components/chat_box.js @@ -18,6 +18,7 @@ import IconButton from 'soapbox/components/icon_button'; const messages = defineMessages({ placeholder: { id: 'chat_box.input.placeholder', defaultMessage: 'Send a messageā€¦' }, + send: { id: 'chat_box.actions.send', defaultMessage: 'Send' }, }); const mapStateToProps = (state, { chatId }) => ({ @@ -164,11 +165,17 @@ class ChatBox extends ImmutablePureComponent { } renderActionButton = () => { + const { intl } = this.props; const { resetFileKey } = this.state; return this.canSubmit() ? (
- +
) : ( From ed4abfdce34ec6e84c3fbcbdf2a83b34ec775226 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 22 Sep 2020 16:20:10 -0500 Subject: [PATCH 2/5] Chats: allow deleting a message, fixes #358 --- app/soapbox/actions/chats.js | 15 ++++++++ .../chats/components/chat_message_list.js | 36 +++++++++++++++++-- app/soapbox/reducers/chat_message_lists.js | 3 ++ app/soapbox/reducers/chat_messages.js | 7 ++++ 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/app/soapbox/actions/chats.js b/app/soapbox/actions/chats.js index 729dc128e..6f8d1c788 100644 --- a/app/soapbox/actions/chats.js +++ b/app/soapbox/actions/chats.js @@ -23,6 +23,10 @@ export const CHAT_READ_REQUEST = 'CHAT_READ_REQUEST'; export const CHAT_READ_SUCCESS = 'CHAT_READ_SUCCESS'; export const CHAT_READ_FAIL = 'CHAT_READ_FAIL'; +export const CHAT_MESSAGE_DELETE_REQUEST = 'CHAT_MESSAGE_DELETE_REQUEST'; +export const CHAT_MESSAGE_DELETE_SUCCESS = 'CHAT_MESSAGE_DELETE_SUCCESS'; +export const CHAT_MESSAGE_DELETE_FAIL = 'CHAT_MESSAGE_DELETE_FAIL'; + export function fetchChats() { return (dispatch, getState) => { dispatch({ type: CHATS_FETCH_REQUEST }); @@ -150,3 +154,14 @@ export function markChatRead(chatId, lastReadId) { }); }; } + +export function deleteChatMessage(chatId, messageId) { + return (dispatch, getState) => { + dispatch({ type: CHAT_MESSAGE_DELETE_REQUEST, chatId, messageId }); + api(getState).delete(`/api/v1/pleroma/chats/${chatId}/messages/${messageId}`).then(({ data }) => { + dispatch({ type: CHAT_MESSAGE_DELETE_SUCCESS, chatId, messageId, chatMessage: data }); + }).catch(error => { + dispatch({ type: CHAT_MESSAGE_DELETE_FAIL, chatId, messageId, error }); + }); + }; +} diff --git a/app/soapbox/features/chats/components/chat_message_list.js b/app/soapbox/features/chats/components/chat_message_list.js index 0c21c6b27..37a7e8ab9 100644 --- a/app/soapbox/features/chats/components/chat_message_list.js +++ b/app/soapbox/features/chats/components/chat_message_list.js @@ -5,16 +5,20 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import { injectIntl, defineMessages } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; -import { fetchChatMessages } from 'soapbox/actions/chats'; +import { fetchChatMessages, deleteChatMessage } from 'soapbox/actions/chats'; import emojify from 'soapbox/features/emoji/emoji'; import classNames from 'classnames'; import { openModal } from 'soapbox/actions/modal'; import { escape, throttle } from 'lodash'; import { MediaGallery } from 'soapbox/features/ui/util/async-components'; import Bundle from 'soapbox/features/ui/components/bundle'; +import DropdownMenuContainer from 'soapbox/containers/dropdown_menu_container'; const messages = defineMessages({ today: { id: 'chats.dividers.today', defaultMessage: 'Today' }, + more: { id: 'chats.actions.more', defaultMessage: 'More' }, + delete: { id: 'chats.actions.delete', defaultMessage: 'Delete message' }, + report: { id: 'chats.actions.report', defaultMessage: 'Report user' }, }); const timeChange = (prev, curr) => { @@ -198,7 +202,8 @@ class ChatMessageList extends ImmutablePureComponent { parseContent = chatMessage => { const content = chatMessage.get('content') || ''; const pending = chatMessage.get('pending', false); - const formatted = pending ? this.parsePendingContent(content) : content; + const deleting = chatMessage.get('deleting', false); + const formatted = (pending && !deleting) ? this.parsePendingContent(content) : content; const emojiMap = makeEmojiMap(chatMessage); return emojify(formatted, emojiMap.toJS()); } @@ -211,8 +216,24 @@ class ChatMessageList extends ImmutablePureComponent {
{text}
) + handleDeleteMessage = (chatId, messageId) => { + return () => { + this.props.dispatch(deleteChatMessage(chatId, messageId)); + }; + } + + handleReportUser = (userId) => { + return () => { + console.log(`should report user ${userId}`); + }; + } + renderMessage = (chatMessage) => { - const { me } = this.props; + const { me, intl } = this.props; + const menu = [ + { text: intl.formatMessage(messages.delete), action: this.handleDeleteMessage(chatMessage.get('chat_id'), chatMessage.get('id')) }, + { text: intl.formatMessage(messages.report), action: this.handleReportUser(chatMessage.get('account_id')) }, + ]; return (
+
+ +
); diff --git a/app/soapbox/reducers/chat_message_lists.js b/app/soapbox/reducers/chat_message_lists.js index 3e2d1dbae..8848a8389 100644 --- a/app/soapbox/reducers/chat_message_lists.js +++ b/app/soapbox/reducers/chat_message_lists.js @@ -3,6 +3,7 @@ import { CHAT_MESSAGES_FETCH_SUCCESS, CHAT_MESSAGE_SEND_REQUEST, CHAT_MESSAGE_SEND_SUCCESS, + CHAT_MESSAGE_DELETE_SUCCESS, } from 'soapbox/actions/chats'; import { STREAMING_CHAT_UPDATE } from 'soapbox/actions/streaming'; import { Map as ImmutableMap, OrderedSet as ImmutableOrderedSet } from 'immutable'; @@ -59,6 +60,8 @@ export default function chatMessageLists(state = initialState, action) { return updateList(state, action.chatId, action.chatMessages.map(chat => chat.id)); case CHAT_MESSAGE_SEND_SUCCESS: return replaceMessage(state, action.chatId, action.uuid, action.chatMessage.id); + case CHAT_MESSAGE_DELETE_SUCCESS: + return state.update(action.chatId, chat => chat.delete(action.messageId)); default: return state; } diff --git a/app/soapbox/reducers/chat_messages.js b/app/soapbox/reducers/chat_messages.js index 74d83ef79..ababe85bd 100644 --- a/app/soapbox/reducers/chat_messages.js +++ b/app/soapbox/reducers/chat_messages.js @@ -3,6 +3,8 @@ import { CHAT_MESSAGES_FETCH_SUCCESS, CHAT_MESSAGE_SEND_REQUEST, CHAT_MESSAGE_SEND_SUCCESS, + CHAT_MESSAGE_DELETE_REQUEST, + CHAT_MESSAGE_DELETE_SUCCESS, } from 'soapbox/actions/chats'; import { STREAMING_CHAT_UPDATE } from 'soapbox/actions/streaming'; import { Map as ImmutableMap, fromJS } from 'immutable'; @@ -43,6 +45,11 @@ export default function chatMessages(state = initialState, action) { return importMessage(state, fromJS(action.chatMessage)).delete(action.uuid); case STREAMING_CHAT_UPDATE: return importLastMessages(state, fromJS([action.chat])); + case CHAT_MESSAGE_DELETE_REQUEST: + return state.update(action.messageId, chatMessage => + chatMessage.set('pending', true).set('deleting', true)); + case CHAT_MESSAGE_DELETE_SUCCESS: + return state.delete(action.messageId); default: return state; } From 41eb69ecd1653d21391debe06ff3b0946e000d29 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 22 Sep 2020 16:34:43 -0500 Subject: [PATCH 3/5] Chats: report user from message, fixes #391 --- app/soapbox/actions/reports.js | 11 +++++++++++ .../features/chats/components/chat_message_list.js | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/soapbox/actions/reports.js b/app/soapbox/actions/reports.js index a1214fc56..9328e0141 100644 --- a/app/soapbox/actions/reports.js +++ b/app/soapbox/actions/reports.js @@ -25,6 +25,17 @@ export function initReport(account, status) { }; }; +export function initReportById(accountId) { + return (dispatch, getState) => { + dispatch({ + type: REPORT_INIT, + account: getState().getIn(['accounts', accountId]), + }); + + dispatch(openModal('REPORT')); + }; +}; + export function cancelReport() { return { type: REPORT_CANCEL, diff --git a/app/soapbox/features/chats/components/chat_message_list.js b/app/soapbox/features/chats/components/chat_message_list.js index 37a7e8ab9..1247c404f 100644 --- a/app/soapbox/features/chats/components/chat_message_list.js +++ b/app/soapbox/features/chats/components/chat_message_list.js @@ -13,6 +13,7 @@ import { escape, throttle } from 'lodash'; import { MediaGallery } from 'soapbox/features/ui/util/async-components'; import Bundle from 'soapbox/features/ui/components/bundle'; import DropdownMenuContainer from 'soapbox/containers/dropdown_menu_container'; +import { initReportById } from 'soapbox/actions/reports'; const messages = defineMessages({ today: { id: 'chats.dividers.today', defaultMessage: 'Today' }, @@ -224,7 +225,7 @@ class ChatMessageList extends ImmutablePureComponent { handleReportUser = (userId) => { return () => { - console.log(`should report user ${userId}`); + this.props.dispatch(initReportById(userId)); }; } From c96c537a528cbfb0bfd4acfb675197849aa1ca90 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 22 Sep 2020 17:00:01 -0500 Subject: [PATCH 4/5] Chats: clean up menu icon --- .../chats/components/chat_message_list.js | 1 + app/styles/chats.scss | 22 ++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/app/soapbox/features/chats/components/chat_message_list.js b/app/soapbox/features/chats/components/chat_message_list.js index 1247c404f..af35f216d 100644 --- a/app/soapbox/features/chats/components/chat_message_list.js +++ b/app/soapbox/features/chats/components/chat_message_list.js @@ -248,6 +248,7 @@ class ChatMessageList extends ImmutablePureComponent { title={this.getFormattedTimestamp(chatMessage)} className='chat-message__bubble' ref={this.setBubbleRef} + tabIndex={0} > {this.maybeRenderMedia(chatMessage)} Date: Tue, 22 Sep 2020 17:02:33 -0500 Subject: [PATCH 5/5] Chats: fix audio toggle on light theme --- app/styles/components/columns.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/styles/components/columns.scss b/app/styles/components/columns.scss index 0351bd008..9dd1a58ea 100644 --- a/app/styles/components/columns.scss +++ b/app/styles/components/columns.scss @@ -713,5 +713,6 @@ .react-toggle-track-check, .react-toggle-track-x { height: 16px; + color: white; } }