From 7ec426e3d8f6581e1f88d2e079a0cd18b70566ec Mon Sep 17 00:00:00 2001 From: mgabdev <> Date: Sat, 19 Dec 2020 01:33:33 -0500 Subject: [PATCH] Progress on DMs Progress on DMs --- .../blocked_chat_accounts_controller.rb | 12 ++--- .../chat_conversation_accounts_controller.rb | 42 ++++++++------- .../api/v1/chat_conversation_controller.rb | 35 ++++++++++++- .../chat_conversations/messages_controller.rb | 6 ++- .../api/v1/chat_messages_controller.rb | 10 +++- .../actions/chat_conversation_accounts.js | 29 ++++++----- .../gabsocial/actions/chat_conversations.js | 12 ++--- .../gabsocial/actions/chat_messages.js | 6 +-- app/javascript/gabsocial/actions/compose.js | 22 ++------ ...conversation_expiration_options_popover.js | 52 +++++++++---------- .../chat_conversation_options_popover.js | 42 ++++++++++----- .../popover/chat_message_options_popover.js | 29 ++++++----- .../status_expiration_options_popover.js | 12 ++--- .../gabsocial/components/status_card.js | 1 - app/javascript/gabsocial/constants.js | 4 +- .../chat_conversations_list_item.js | 13 +++-- .../components/chat_message_compose_form.js | 39 +++++++++++--- .../messages/components/chat_message_item.js | 23 ++++++-- .../components/chat_message_scrolling_list.js | 15 +++--- .../components/chat_settings_sidebar.js | 6 ++- app/javascript/gabsocial/features/ui/ui.js | 1 + .../reducers/chat_conversation_messages.js | 4 ++ .../gabsocial/reducers/chat_conversations.js | 2 + .../gabsocial/reducers/relationships.js | 12 ++++- app/javascript/gabsocial/utils/urls.js | 1 + app/models/chat_conversation_account.rb | 2 +- app/models/chat_message.rb | 1 + app/models/concerns/account_interactions.rb | 25 +++++++++ .../account_relationships_presenter.rb | 11 ++-- .../chat_conversation_account_serializer.rb | 19 +++++++ .../rest/chat_messenger_blocked_serializer.rb | 18 +++++++ app/services/delete_chat_message_service.rb | 25 ++++++--- app/services/post_chat_message_service.rb | 52 ++++++++++++------- app/services/post_status_service.rb | 18 ++++++- app/workers/delete_chat_message_worker.rb | 12 +++++ .../expiring_chat_messages_scheduler.rb | 17 ++++++ config/routes.rb | 11 ++-- config/sidekiq.yml | 3 ++ 38 files changed, 447 insertions(+), 197 deletions(-) create mode 100644 app/serializers/rest/chat_messenger_blocked_serializer.rb create mode 100644 app/workers/delete_chat_message_worker.rb create mode 100644 app/workers/scheduler/expiring_chat_messages_scheduler.rb diff --git a/app/controllers/api/v1/chat_conversation_accounts/blocked_chat_accounts_controller.rb b/app/controllers/api/v1/chat_conversation_accounts/blocked_chat_accounts_controller.rb index 2ff84ee2..a7b52de0 100644 --- a/app/controllers/api/v1/chat_conversation_accounts/blocked_chat_accounts_controller.rb +++ b/app/controllers/api/v1/chat_conversation_accounts/blocked_chat_accounts_controller.rb @@ -18,12 +18,12 @@ class Api::V1::ChatConversationAccounts::BlockedChatAccountsController < Api::Ba def paginated_blocks @paginated_blocks ||= ChatBlock.eager_load(target_account: :account_stat) - .where(account: current_account) - .paginate_by_max_id( - limit_param(DEFAULT_ACCOUNTS_LIMIT), - params[:max_id], - params[:since_id] - ) + .where(account: current_account) + .paginate_by_max_id( + limit_param(DEFAULT_ACCOUNTS_LIMIT), + params[:max_id], + params[:since_id] + ) end def insert_pagination_headers diff --git a/app/controllers/api/v1/chat_conversation_accounts_controller.rb b/app/controllers/api/v1/chat_conversation_accounts_controller.rb index e1bd8e22..35968577 100644 --- a/app/controllers/api/v1/chat_conversation_accounts_controller.rb +++ b/app/controllers/api/v1/chat_conversation_accounts_controller.rb @@ -5,43 +5,47 @@ class Api::V1::ChatConversationAccountsController < Api::BaseController before_action -> { doorkeeper_authorize! :write, :'write:chats' } before_action :require_user! - before_action :set_account + before_action :set_account, only: [:block_messenger, :unblock_messenger, :messenger_block_relationships] + before_action :check_account_suspension, only: [:block_messenger, :unblock_messenger, :messenger_block_relationships] + before_action :set_chat_conversation, except: [:block_messenger, :unblock_messenger, :messenger_block_relationships] def block_messenger - BlockMessengerService.new.call(current_user.account, @account) - render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships + @block = BlockChatMessengerService.new.call(current_user.account, @account) + render json: @account, + serializer: REST::ChatMessengerBlockedSerializer, + chat_blocking: true end def unblock_messenger - UnblockMessengerService.new.call(current_user.account, @account) - render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships + UnblockChatMessengerService.new.call(current_user.account, @account) + render json: @account, + serializer: REST::ChatMessengerBlockedSerializer, + chat_blocking: false + end + + def messenger_block_relationships + chat_blocking = current_user.account.chat_blocking?(@account) + chat_blocked_by = current_user.account.chat_blocked_by?(@account, current_account) + render json: @account, + serializer: REST::ChatMessengerBlockedSerializer, + chat_blocking: chat_blocking, + chat_blocked_by: chat_blocked_by end def mute_chat_conversation - @chat_conversation_account.is_muted = true - @chat_conversation_account.save! + @chat_conversation_account.update!(is_muted: true) render json: @chat_conversation_account, serializer: REST::ChatConversationAccountSerializer end def unmute_chat_conversation - @chat_conversation_account.is_muted = false - @chat_conversation_account.save! + @chat_conversation_account.update!(is_muted: false) render json: @chat_conversation_account, serializer: REST::ChatConversationAccountSerializer end - def set_expiration_policy - if current_user.account.is_pro - # : todo : - render json: @chat_conversation_account, serializer: REST::ChatConversationAccountSerializer - else - render json: { error: 'You need to be a GabPRO member to access this' }, status: 422 - end - end - private def set_account - @account = Account.find(params[:id]) + @account = Account.find(params[:account_id]) end def set_chat_conversation diff --git a/app/controllers/api/v1/chat_conversation_controller.rb b/app/controllers/api/v1/chat_conversation_controller.rb index 13d48583..8a146645 100644 --- a/app/controllers/api/v1/chat_conversation_controller.rb +++ b/app/controllers/api/v1/chat_conversation_controller.rb @@ -6,7 +6,13 @@ class Api::V1::ChatConversationController < Api::BaseController before_action :require_user! before_action :set_account, only: :create - before_action :set_chat_conversation, only: [:show, :mark_chat_conversation_approved, :mark_chat_conversation_hidden, :mark_chat_conversation_read] + before_action :set_chat_conversation, only: [ + :show, + :mark_chat_conversation_approved, + :mark_chat_conversation_hidden, + :mark_chat_conversation_read, + :set_expiration_policy + ] def show render json: {}, each_serializer: REST::ChatConversationAccountSerializer @@ -43,6 +49,33 @@ class Api::V1::ChatConversationController < Api::BaseController end end + def set_expiration_policy + if current_user.account.is_pro + case params[:expiration] + when 'five_minutes' + @expires_at = ChatConversationAccount::EXPIRATION_POLICY_MAP[:five_minutes] + when 'one_hour' + @expires_at = ChatConversationAccount::EXPIRATION_POLICY_MAP[:one_hour] + when 'six_hours' + @expires_at = ChatConversationAccount::EXPIRATION_POLICY_MAP[:six_hours] + when 'one_day' + @expires_at = ChatConversationAccount::EXPIRATION_POLICY_MAP[:one_day] + when 'three_days' + @expires_at = ChatConversationAccount::EXPIRATION_POLICY_MAP[:three_days] + when 'one_week' + @expires_at = ChatConversationAccount::EXPIRATION_POLICY_MAP[:one_week] + else + @expires_at = nil + end + puts "tilly @expires_at: " + @expires_at.inspect + @chat_conversation_account.chat_message_expiration_policy = @expires_at + @chat_conversation_account.save! + render json: @chat_conversation_account, serializer: REST::ChatConversationAccountSerializer + else + render json: { error: 'You need to be a GabPRO member to access this' }, status: 422 + end + end + private def find_or_create_conversation diff --git a/app/controllers/api/v1/chat_conversations/messages_controller.rb b/app/controllers/api/v1/chat_conversations/messages_controller.rb index c0e0aa13..8cd8f87b 100644 --- a/app/controllers/api/v1/chat_conversations/messages_controller.rb +++ b/app/controllers/api/v1/chat_conversations/messages_controller.rb @@ -16,7 +16,11 @@ class Api::V1::ChatConversations::MessagesController < Api::BaseController def destroy_all if current_user.account.is_pro - @chat_conversation_account = PurgeChatMessagesService.new.call(current_user.account, @chat_conversation) + PurgeChatMessagesService.new.call(current_user.account, @chat_conversation) + @chat_conversation_account = ChatConversationAccount.where( + account: current_user.account, + chat_conversation: @chat_conversation + ).first render json: @chat_conversation_account, serializer: REST::ChatConversationAccountSerializer else render json: { error: 'You need to be a GabPRO member to access this' }, status: 422 diff --git a/app/controllers/api/v1/chat_messages_controller.rb b/app/controllers/api/v1/chat_messages_controller.rb index ec6a1b56..91808668 100644 --- a/app/controllers/api/v1/chat_messages_controller.rb +++ b/app/controllers/api/v1/chat_messages_controller.rb @@ -5,6 +5,7 @@ class Api::V1::ChatMessagesController < Api::BaseController before_action -> { doorkeeper_authorize! :write, :'write:chats' } before_action :require_user! + before_action :set_chat_message, only: :destroy def create @chat_conversation = ChatConversation.find(chat_params[:chat_conversation_id]) @@ -13,8 +14,9 @@ class Api::V1::ChatMessagesController < Api::BaseController end def destroy - @chat = DeleteChatMessageService.new.call(current_user.account, params[:id]) - render json: @chat, serializer: REST::ChatMessageSerializer + return not_found if @chatMessage.nil? + DeleteChatMessageService.new.call(@chatMessage) + render json: @chatMessage, serializer: REST::ChatMessageSerializer end private @@ -23,4 +25,8 @@ class Api::V1::ChatMessagesController < Api::BaseController params.permit(:text, :chat_conversation_id) end + def set_chat_message + @chatMessage = ChatMessage.where(from_account: current_user.account).find(params[:id]) + end + end diff --git a/app/javascript/gabsocial/actions/chat_conversation_accounts.js b/app/javascript/gabsocial/actions/chat_conversation_accounts.js index e895a19d..10e68ba5 100644 --- a/app/javascript/gabsocial/actions/chat_conversation_accounts.js +++ b/app/javascript/gabsocial/actions/chat_conversation_accounts.js @@ -20,7 +20,7 @@ export const UNBLOCK_CHAT_MESSAGER_REQUEST = 'UNBLOCK_CHAT_MESSAGER_REQUEST' export const UNBLOCK_CHAT_MESSAGER_SUCCESS = 'UNBLOCK_CHAT_MESSAGER_SUCCESS' export const UNBLOCK_CHAT_MESSAGER_FAIL = 'UNBLOCK_CHAT_MESSAGER_FAIL' -export const IS_CHAT_MESSENGER_BLOCKED_SUCCESS = 'IS_CHAT_MESSENGER_BLOCKED_SUCCESS' +export const FETCH_CHAT_MESSENGER_BLOCKING_RELATIONSHIPS_SUCCESS = 'FETCH_CHAT_MESSENGER_BLOCKING_RELATIONSHIPS_SUCCESS' // @@ -36,13 +36,12 @@ export const UNMUTE_CHAT_CONVERSATION_FAIL = 'UNMUTE_CHAT_CONVERSATION_FAIL' * */ export const blockChatMessenger = (accountId) => (dispatch, getState) => { - console.log("blockChatMessenger:", accountId) if (!me || !accountId) return dispatch(blockChatMessengerRequest(accountId)) - api(getState).post(`/api/v1/chat_conversation_accounts/${accountId}/block_messenger`).then((response) => { - dispatch(blockChatMessengerSuccess()) + api(getState).post(`/api/v1/chat_conversation_accounts/_/block_messenger`, { account_id: accountId }).then((response) => { + dispatch(blockChatMessengerSuccess(response.data)) }).catch((error) => { dispatch(blockChatMessengerFail(accountId, error)) }) @@ -53,8 +52,9 @@ const blockChatMessengerRequest = (accountId) => ({ accountId, }) -const blockChatMessengerSuccess = () => ({ +const blockChatMessengerSuccess = (data) => ({ type: BLOCK_CHAT_MESSAGER_SUCCESS, + data, showToast: true, }) @@ -73,8 +73,8 @@ export const unblockChatMessenger = (accountId) => (dispatch, getState) => { dispatch(unblockChatMessengerRequest(accountId)) - api(getState).post(`/api/v1/chat_conversation_accounts/${accountId}/unblock_messenger`).then((response) => { - dispatch(unblockChatMessengerSuccess()) + api(getState).post(`/api/v1/chat_conversation_accounts/_/unblock_messenger`, { account_id: accountId }).then((response) => { + dispatch(unblockChatMessengerSuccess(response.data)) }).catch((error) => { dispatch(unblockChatMessengerFail(accountId, error)) }) @@ -85,8 +85,9 @@ const unblockChatMessengerRequest = (accountId) => ({ accountId, }) -const unblockChatMessengerSuccess = () => ({ +const unblockChatMessengerSuccess = (data) => ({ type: UNBLOCK_CHAT_MESSAGER_SUCCESS, + data, showToast: true, }) @@ -101,16 +102,16 @@ const unblockChatMessengerFail = (accountId, error) => ({ * @description Check if a chat messenger is blocked by the current user account. * @param {String} accountId */ -export const isChatMessengerBlocked = (accountId) => (dispatch, getState) => { +export const fetchMessengerBlockingRelationships = (accountId) => (dispatch, getState) => { if (!me || !accountId) return - api(getState).post(`/api/v1/chat_conversation_accounts/${accountId}/is_messenger_blocked`).then((response) => { - dispatch(isChatMessengerBlockedSuccess(response.data)) + api(getState).post(`/api/v1/chat_conversation_accounts/_/messenger_block_relationships`, { account_id: accountId }).then((response) => { + dispatch(fetchMessengerBlockingRelationshipsSuccess(response.data)) }) } -const isChatMessengerBlockedSuccess = (data) => ({ - type: IS_CHAT_MESSENGER_BLOCKED_SUCCESS, +const fetchMessengerBlockingRelationshipsSuccess = (data) => ({ + type: FETCH_CHAT_MESSENGER_BLOCKING_RELATIONSHIPS_SUCCESS, data, }) @@ -193,7 +194,7 @@ export const muteChatConversation = (chatConversationId) => (dispatch, getState) api(getState).post(`/api/v1/chat_conversation_accounts/${chatConversationId}/mute_chat_conversation`).then((response) => { dispatch(muteChatConversationSuccess(response.data)) }).catch((error) => { - dispatch(muteChatMessengerFail(error)) + dispatch(muteChatConversationFail(error)) }) } diff --git a/app/javascript/gabsocial/actions/chat_conversations.js b/app/javascript/gabsocial/actions/chat_conversations.js index 36ac51a1..3386009d 100644 --- a/app/javascript/gabsocial/actions/chat_conversations.js +++ b/app/javascript/gabsocial/actions/chat_conversations.js @@ -389,9 +389,9 @@ export const readChatConversationFail = () => ({ * */ export const setChatConversationExpiration = (chatConversationId, expiration) => (dispatch, getState) => { - if (!me|| !chatConversationId || !expiration) return + if (!me|| !chatConversationId) return - dispatch(setChatConversationExpirationFetch(chatConversation)) + dispatch(setChatConversationExpirationFetch(chatConversationId)) api(getState).post(`/api/v1/chat_conversation/${chatConversationId}/set_expiration_policy`, { expiration, @@ -400,18 +400,18 @@ export const setChatConversationExpiration = (chatConversationId, expiration) => }).catch((error) => dispatch(setChatConversationExpirationFail(error))) } -export const setChatConversationExpirationFetch = (chatConversation) => ({ +export const setChatConversationExpirationFetch = (chatConversationId) => ({ type: SET_CHAT_CONVERSATION_EXPIRATION_REQUEST, - chatConversation, + chatConversationId, }) export const setChatConversationExpirationSuccess = (chatConversation) => ({ - type: SET_CHAT_CONVERSATION_EXPIRATION_REQUEST, + type: SET_CHAT_CONVERSATION_EXPIRATION_SUCCESS, chatConversation, }) export const setChatConversationExpirationFail = (error) => ({ - type: SET_CHAT_CONVERSATION_EXPIRATION_REQUEST, + type: SET_CHAT_CONVERSATION_EXPIRATION_FAIL, error, }) diff --git a/app/javascript/gabsocial/actions/chat_messages.js b/app/javascript/gabsocial/actions/chat_messages.js index 3cb046ad..43e85700 100644 --- a/app/javascript/gabsocial/actions/chat_messages.js +++ b/app/javascript/gabsocial/actions/chat_messages.js @@ -113,12 +113,12 @@ const deleteChatMessageFail = (error) => ({ export const purgeChatMessages = (chatConversationId) => (dispatch, getState) => { if (!me || !chatConversationId) return - dispatch(deleteChatMessagesRequest(chatConversationId)) + dispatch(purgeChatMessagesRequest(chatConversationId)) api(getState).delete(`/api/v1/chat_conversations/messages/${chatConversationId}/destroy_all`).then((response) => { - dispatch(deleteChatMessagesSuccess(response.data)) + dispatch(purgeChatMessagesSuccess(chatConversationId)) }).catch((error) => { - dispatch(deleteChatMessagesFail(error)) + dispatch(purgeChatMessagesFail(error)) }) } diff --git a/app/javascript/gabsocial/actions/compose.js b/app/javascript/gabsocial/actions/compose.js index a0bf17b6..fa8d0ac2 100644 --- a/app/javascript/gabsocial/actions/compose.js +++ b/app/javascript/gabsocial/actions/compose.js @@ -21,9 +21,9 @@ import { openModal, closeModal } from './modal' import { MODAL_COMPOSE, EXPIRATION_OPTION_5_MINUTES, - EXPIRATION_OPTION_60_MINUTES, + EXPIRATION_OPTION_1_HOUR, EXPIRATION_OPTION_6_HOURS, - EXPIRATION_OPTION_24_HOURS, + EXPIRATION_OPTION_1_DAY, EXPIRATION_OPTION_3_DAYS, EXPIRATION_OPTION_7_DAYS, } from '../constants' @@ -345,23 +345,7 @@ export const submitCompose = (groupId, replyToId = null, router, isStandalone, a let scheduled_at = getState().getIn(['compose', 'scheduled_at'], null) if (scheduled_at !== null) scheduled_at = moment.utc(scheduled_at).toDate() - let expires_at = getState().getIn(['compose', 'expires_at'], null) - - if (expires_at) { - if (expires_at === EXPIRATION_OPTION_5_MINUTES) { - expires_at = moment.utc().add('5', 'minute').toDate() - } else if (expires_at === EXPIRATION_OPTION_60_MINUTES) { - expires_at = moment.utc().add('60', 'minute').toDate() - } else if (expires_at === EXPIRATION_OPTION_6_HOURS) { - expires_at = moment.utc().add('6', 'hour').toDate() - } else if (expires_at === EXPIRATION_OPTION_24_HOURS) { - expires_at = moment.utc().add('24', 'hour').toDate() - } else if (expires_at === EXPIRATION_OPTION_3_DAYS) { - expires_at = moment.utc().add('3', 'day').toDate() - } else if (expires_at === EXPIRATION_OPTION_7_DAYS) { - expires_at = moment.utc().add('7', 'day').toDate() - } - } + const expires_at = getState().getIn(['compose', 'expires_at'], null) if (isMobile(window.innerWidth) && router && isStandalone) { router.history.goBack() diff --git a/app/javascript/gabsocial/components/popover/chat_conversation_expiration_options_popover.js b/app/javascript/gabsocial/components/popover/chat_conversation_expiration_options_popover.js index 1acccaca..7ed1409b 100644 --- a/app/javascript/gabsocial/components/popover/chat_conversation_expiration_options_popover.js +++ b/app/javascript/gabsocial/components/popover/chat_conversation_expiration_options_popover.js @@ -3,12 +3,12 @@ import PropTypes from 'prop-types' import { connect } from 'react-redux' import { defineMessages, injectIntl } from 'react-intl' import { closePopover } from '../../actions/popover' -import { changeExpiresAt } from '../../actions/compose' +import { setChatConversationExpiration } from '../../actions/chat_conversations' import { EXPIRATION_OPTION_5_MINUTES, - EXPIRATION_OPTION_60_MINUTES, + EXPIRATION_OPTION_1_HOUR, EXPIRATION_OPTION_6_HOURS, - EXPIRATION_OPTION_24_HOURS, + EXPIRATION_OPTION_1_DAY, EXPIRATION_OPTION_3_DAYS, EXPIRATION_OPTION_7_DAYS, } from '../../constants' @@ -19,7 +19,7 @@ import Text from '../text' class ChatConversationExpirationOptionsPopover extends React.PureComponent { handleOnSetExpiration = (expiresAt) => { - this.props.onChangeExpiresAt(expiresAt) + this.props.onSetChatConversationExpiration(expiresAt) this.handleOnClosePopover() } @@ -29,66 +29,62 @@ class ChatConversationExpirationOptionsPopover extends React.PureComponent { render() { const { + chatConversationId, expiresAtValue, intl, isXS, } = this.props + console.log("expiresAtValue:", expiresAtValue) + if (!chatConversationId) return
+ const listItems = [ { hideArrow: true, title: 'None', - onClick: () => this.handleOnSetStatusExpiration(null), + onClick: () => this.handleOnSetExpiration(null), isActive: !expiresAtValue, }, { hideArrow: true, title: intl.formatMessage(messages.minutes, { number: 5 }), - onClick: () => this.handleOnSetStatusExpiration(EXPIRATION_OPTION_5_MINUTES), + onClick: () => this.handleOnSetExpiration(EXPIRATION_OPTION_5_MINUTES), isActive: expiresAtValue === EXPIRATION_OPTION_5_MINUTES, }, { hideArrow: true, title: intl.formatMessage(messages.minutes, { number: 60 }), - onClick: () => this.handleOnSetStatusExpiration(EXPIRATION_OPTION_60_MINUTES), - isActive: expiresAtValue === EXPIRATION_OPTION_60_MINUTES, + onClick: () => this.handleOnSetExpiration(EXPIRATION_OPTION_1_HOUR), + isActive: expiresAtValue === EXPIRATION_OPTION_1_HOUR, }, { hideArrow: true, title: '6 hours', title: intl.formatMessage(messages.hours, { number: 6 }), - onClick: () => this.handleOnSetStatusExpiration(EXPIRATION_OPTION_6_HOURS), + onClick: () => this.handleOnSetExpiration(EXPIRATION_OPTION_6_HOURS), isActive: expiresAtValue === EXPIRATION_OPTION_6_HOURS, }, { hideArrow: true, title: intl.formatMessage(messages.hours, { number: 24 }), - onClick: () => this.handleOnSetStatusExpiration(EXPIRATION_OPTION_24_HOURS), - isActive: expiresAtValue === EXPIRATION_OPTION_24_HOURS, + onClick: () => this.handleOnSetExpiration(EXPIRATION_OPTION_1_DAY), + isActive: expiresAtValue === EXPIRATION_OPTION_1_DAY, }, { hideArrow: true, title: '3 days', title: intl.formatMessage(messages.days, { number: 3 }), - onClick: () => this.handleOnSetStatusExpiration(EXPIRATION_OPTION_3_DAYS), + onClick: () => this.handleOnSetExpiration(EXPIRATION_OPTION_3_DAYS), isActive: expiresAtValue === EXPIRATION_OPTION_3_DAYS, }, { hideArrow: true, title: intl.formatMessage(messages.days, { number: 7 }), - onClick: () => this.handleOnSetStatusExpiration(EXPIRATION_OPTION_7_DAYS), + onClick: () => this.handleOnSetExpiration(EXPIRATION_OPTION_7_DAYS), isActive: expiresAtValue === EXPIRATION_OPTION_7_DAYS, }, ] - if (expiresAtValue) { - listItems.unshift({ - hideArrow: true, - title: 'Remove expiration', - onClick: () => this.handleOnSetStatusExpiration(null), - },) - } - return ( ({ - expiresAtValue: state.getIn(['compose', 'expires_at']), +const mapStateToProps = (state, { chatConversationId }) => ({ + expiresAtValue: state.getIn(['chat_conversations', chatConversationId, 'chat_message_expiration_policy']), }) -const mapDispatchToProps = (dispatch) => ({ - onChangeExpiresAt(expiresAt) { - dispatch(changeExpiresAt(expiresAt)) - }, +const mapDispatchToProps = (dispatch, { chatConversationId }) => ({ onClosePopover() { dispatch(closePopover()) }, + onSetChatConversationExpiration(expiration) { + dispatch(setChatConversationExpiration(chatConversationId, expiration)) + }, }) ChatConversationExpirationOptionsPopover.defaultProps = { expiresAtValue: PropTypes.string.isRequired, intl: PropTypes.object.isRequired, isXS: PropTypes.bool, - onChangeExpiresAt: PropTypes.func.isRequired, + onSetChatConversationExpiration: PropTypes.func.isRequired, } export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ChatConversationExpirationOptionsPopover)) \ No newline at end of file diff --git a/app/javascript/gabsocial/components/popover/chat_conversation_options_popover.js b/app/javascript/gabsocial/components/popover/chat_conversation_options_popover.js index df1429f4..4e1c1ddf 100644 --- a/app/javascript/gabsocial/components/popover/chat_conversation_options_popover.js +++ b/app/javascript/gabsocial/components/popover/chat_conversation_options_popover.js @@ -6,6 +6,10 @@ import { connect } from 'react-redux' import { closePopover } from '../../actions/popover' import { openModal } from '../../actions/modal' import { hideChatConversation } from '../../actions/chat_conversations' +import { + muteChatConversation, + unmuteChatConversation, +} from '../../actions/chat_conversation_accounts' import { purgeChatMessages } from '../../actions/chat_messages' import { MODAL_PRO_UPGRADE } from '../../constants' import { me } from '../../initial_state' @@ -21,8 +25,12 @@ class ChatConversationOptionsPopover extends ImmutablePureComponent { this.handleOnClosePopover() } - handleOnUnmute = () => { - this.props.onUnute() + handleOnMute = () => { + if (this.props.isMuted) { + this.props.onUnmute() + } else { + this.props.onMute() + } this.handleOnClosePopover() } @@ -30,7 +38,7 @@ class ChatConversationOptionsPopover extends ImmutablePureComponent { if (!this.props.isPro) { this.props.openProUpgradeModal() } else { - this.props.onPurge(this.props.chatConversationId) + this.props.onPurge() } this.handleOnClosePopover() @@ -44,6 +52,7 @@ class ChatConversationOptionsPopover extends ImmutablePureComponent { const { intl, isXS, + isMuted, } = this.props const items = [ @@ -55,9 +64,9 @@ class ChatConversationOptionsPopover extends ImmutablePureComponent { }, { hideArrow: true, - title: 'Mute Conversation', - subtitle: "Don't get notified of new messages", - onClick: () => this.handleOnHide(), + title: isMuted ? 'Unmute Conversation' : 'Mute Conversation', + subtitle: isMuted ? null : "Don't get notified of new messages", + onClick: () => this.handleOnMute(), }, {}, { @@ -86,23 +95,28 @@ class ChatConversationOptionsPopover extends ImmutablePureComponent { const mapStateToProps = (state, { chatConversationId }) => ({ isPro: state.getIn(['accounts', me, 'is_pro']), - chatConversation: makeGetChatConversation()(state, { id: chatConversationId }), + isMuted: state.getIn(['chat_conversations', chatConversationId, 'is_muted']), }) -const mapDispatchToProps = (dispatch) => ({ +const mapDispatchToProps = (dispatch, { chatConversationId }) => ({ openProUpgradeModal() { dispatch(openModal(MODAL_PRO_UPGRADE)) }, - onSetCommentSortingSetting(type) { - dispatch(closePopover()) - }, - onPurge(chatConversationId) { + onPurge() { dispatch(purgeChatMessages(chatConversationId)) }, - onHide(chatConversationId) { + onHide() { dispatch(hideChatConversation(chatConversationId)) }, - onClosePopover: () => dispatch(closePopover()), + onMute() { + dispatch(muteChatConversation(chatConversationId)) + }, + onUnmute() { + dispatch(unmuteChatConversation(chatConversationId)) + }, + onClosePopover() { + dispatch(closePopover()) + }, }) ChatConversationOptionsPopover.propTypes = { diff --git a/app/javascript/gabsocial/components/popover/chat_message_options_popover.js b/app/javascript/gabsocial/components/popover/chat_message_options_popover.js index 0b86521d..ebce126a 100644 --- a/app/javascript/gabsocial/components/popover/chat_message_options_popover.js +++ b/app/javascript/gabsocial/components/popover/chat_message_options_popover.js @@ -4,11 +4,11 @@ import { connect } from 'react-redux' import { closePopover } from '../../actions/popover' import { deleteChatMessage } from '../../actions/chat_messages' import { + fetchMessengerBlockingRelationships, blockChatMessenger, unblockChatMessenger, - reportChatMessage, + // reportChatMessage, } from '../../actions/chat_conversation_accounts' -import { fetchRelationships } from '../../actions/accounts' import { makeGetChatMessage } from '../../selectors' import { me } from '../../initial_state' import PopoverLayout from './popover_layout' @@ -20,7 +20,7 @@ class ChatMessageOptionsPopover extends React.PureComponent { componentDidMount() { if (!this.props.isMine) { - this.props.onFetchRelationships(this.props.fromAccountId) + this.props.onFetchMessengerBlockingRelationships(this.props.fromAccountId) } } @@ -33,7 +33,7 @@ class ChatMessageOptionsPopover extends React.PureComponent { } handleOnBlock = () => { - if (this.props.isBlocked) { + if (this.props.isChatBlocked) { this.props.onUnblock(this.props.fromAccountId) } else { this.props.onBlock(this.props.fromAccountId) @@ -48,7 +48,7 @@ class ChatMessageOptionsPopover extends React.PureComponent { const { isXS, isMine, - isBlocked, + isChatBlocked, } = this.props const items = isMine ? [ @@ -66,8 +66,8 @@ class ChatMessageOptionsPopover extends React.PureComponent { {}, { hideArrow: true, - title: isBlocked ? 'Unblock Messenger' : 'Block Messenger', - subtitle: isBlocked ? '' : 'The messenger will not be able to message you.', + title: isChatBlocked ? 'Unblock Messenger' : 'Block Messenger', + subtitle: isChatBlocked ? null : 'The messenger will not be able to message you.', onClick: () => this.handleOnBlock(), }, ] @@ -90,7 +90,7 @@ const mapStateToProps = (state, { chatMessageId }) => { return { fromAccountId, isMine: fromAccountId === me, - isBlocked: state.getIn(['relationships', fromAccountId, 'chat_blocked_by'], false), + isChatBlocked: state.getIn(['relationships', fromAccountId, 'chat_blocking'], false), } } @@ -101,15 +101,19 @@ const mapDispatchToProps = (dispatch) => ({ }, onBlock(accountId) { dispatch(blockChatMessenger(accountId)) + dispatch(closePopover()) }, onUnblock(accountId) { dispatch(unblockChatMessenger(accountId)) + dispatch(closePopover()) }, onReportChatMessage(chatMessageId) { - dispatch(reportChatMessage(chatMessageId)) + // : todo : + // dispatch(reportChatMessage(chatMessageId)) + dispatch(closePopover()) }, - onFetchRelationships(accountId) { - // dispatch(fetchRelationships(accountId)) + onFetchMessengerBlockingRelationships(accountId) { + dispatch(fetchMessengerBlockingRelationships(accountId)) }, onClosePopover() { dispatch(closePopover()) @@ -120,8 +124,9 @@ ChatMessageOptionsPopover.propTypes = { isXS: PropTypes.bool, isMine: PropTypes.bool, chatMessageId: PropTypes.string.isRequired, - isBlocked: PropTypes.bool.isRequired, + isChatBlocked: PropTypes.bool.isRequired, onDeleteChatMessage: PropTypes.func.isRequired, + onIsChatMessengerBlocked: PropTypes.func.isRequired, } export default connect(mapStateToProps, mapDispatchToProps)(ChatMessageOptionsPopover) \ No newline at end of file diff --git a/app/javascript/gabsocial/components/popover/status_expiration_options_popover.js b/app/javascript/gabsocial/components/popover/status_expiration_options_popover.js index 61108332..45b5c472 100644 --- a/app/javascript/gabsocial/components/popover/status_expiration_options_popover.js +++ b/app/javascript/gabsocial/components/popover/status_expiration_options_popover.js @@ -6,9 +6,9 @@ import { closePopover } from '../../actions/popover' import { changeExpiresAt } from '../../actions/compose' import { EXPIRATION_OPTION_5_MINUTES, - EXPIRATION_OPTION_60_MINUTES, + EXPIRATION_OPTION_1_HOUR, EXPIRATION_OPTION_6_HOURS, - EXPIRATION_OPTION_24_HOURS, + EXPIRATION_OPTION_1_DAY, EXPIRATION_OPTION_3_DAYS, EXPIRATION_OPTION_7_DAYS, } from '../../constants' @@ -50,8 +50,8 @@ class StatusExpirationOptionsPopover extends React.PureComponent { { hideArrow: true, title: intl.formatMessage(messages.minutes, { number: 60 }), - onClick: () => this.handleOnSetStatusExpiration(EXPIRATION_OPTION_60_MINUTES), - isActive: expiresAtValue === EXPIRATION_OPTION_60_MINUTES, + onClick: () => this.handleOnSetStatusExpiration(EXPIRATION_OPTION_1_HOUR), + isActive: expiresAtValue === EXPIRATION_OPTION_1_HOUR, }, { hideArrow: true, @@ -63,8 +63,8 @@ class StatusExpirationOptionsPopover extends React.PureComponent { { hideArrow: true, title: intl.formatMessage(messages.hours, { number: 24 }), - onClick: () => this.handleOnSetStatusExpiration(EXPIRATION_OPTION_24_HOURS), - isActive: expiresAtValue === EXPIRATION_OPTION_24_HOURS, + onClick: () => this.handleOnSetStatusExpiration(EXPIRATION_OPTION_1_DAY), + isActive: expiresAtValue === EXPIRATION_OPTION_1_DAY, }, { hideArrow: true, diff --git a/app/javascript/gabsocial/components/status_card.js b/app/javascript/gabsocial/components/status_card.js index a721d1f8..3fa1e73e 100644 --- a/app/javascript/gabsocial/components/status_card.js +++ b/app/javascript/gabsocial/components/status_card.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types' import Immutable from 'immutable' import ImmutablePropTypes from 'react-immutable-proptypes' import ImmutablePureComponent from 'react-immutable-pure-component' -import punycode from 'punycode' import { CX, DEFAULT_REL, diff --git a/app/javascript/gabsocial/constants.js b/app/javascript/gabsocial/constants.js index bfcb0f45..52cbcf49 100644 --- a/app/javascript/gabsocial/constants.js +++ b/app/javascript/gabsocial/constants.js @@ -134,9 +134,9 @@ export const GAB_COM_INTRODUCE_YOURSELF_GROUP_ID = '12' export const MIN_ACCOUNT_CREATED_AT_ONBOARDING = 1594789200000 // 2020-07-15 export const EXPIRATION_OPTION_5_MINUTES = 'five_minutes' -export const EXPIRATION_OPTION_60_MINUTES = 'one_hour' +export const EXPIRATION_OPTION_1_HOUR = 'one_hour' export const EXPIRATION_OPTION_6_HOURS = 'six_hours' -export const EXPIRATION_OPTION_24_HOURS = 'one_day' +export const EXPIRATION_OPTION_1_DAY = 'one_day' export const EXPIRATION_OPTION_3_DAYS = 'three_days' export const EXPIRATION_OPTION_7_DAYS = 'one_week' diff --git a/app/javascript/gabsocial/features/messages/components/chat_conversations_list_item.js b/app/javascript/gabsocial/features/messages/components/chat_conversations_list_item.js index bbda7730..29924cbb 100644 --- a/app/javascript/gabsocial/features/messages/components/chat_conversations_list_item.js +++ b/app/javascript/gabsocial/features/messages/components/chat_conversations_list_item.js @@ -7,6 +7,7 @@ import { makeGetChatConversation } from '../../../selectors' import { setChatConversationSelected } from '../../../actions/chats' import { CX } from '../../../constants' import Input from '../../../components/input' +import Icon from '../../../components/icon' import DisplayNameGroup from '../../../components/display_name_group' import DisplayName from '../../../components/display_name' import AvatarGroup from '../../../components/avatar_group' @@ -35,8 +36,6 @@ class ChatConversationsListItem extends ImmutablePureComponent { if (!chatConversation) return
- console.log("chatConversation:", chatConversation) - const containerClasses = CX({ d: 1, w100PC: 1, @@ -66,6 +65,8 @@ class ChatConversationsListItem extends ImmutablePureComponent { lastMessageText = lastMessageText.length >= 28 ? `${lastMessageText.substring(0, 28).trim()}...` : lastMessageText const content = { __html: lastMessageText } const date = !!lastMessage ? lastMessage.get('created_at') : chatConversation.get('created_at') + const isUnread = chatConversation.get('is_unread') + const isMuted = chatConversation.get('is_muted') return (