Progress on deck, dms

This commit is contained in:
mgabdev 2020-12-10 11:51:45 -05:00
parent c35e651b43
commit de0c977950
40 changed files with 660 additions and 274 deletions

@ -0,0 +1 @@
{}

@ -1,11 +1,11 @@
# frozen_string_literal: true
class Api::V1::ChatConversationAccounts::BlockedAccountsController < Api::BaseController
class Api::V1::ChatConversationAccounts::BlockedChatAccountsController < Api::BaseController
before_action -> { doorkeeper_authorize! :follow, :'read:blocks' }
before_action :require_user!
after_action :insert_pagination_headers
def index
def show
@accounts = load_accounts
render json: @accounts, each_serializer: REST::AccountSerializer
end
@ -32,13 +32,13 @@ class Api::V1::ChatConversationAccounts::BlockedAccountsController < Api::BaseCo
def next_path
if records_continue?
api_v1_chat_conversation_accounts_blocked_accounts_url pagination_params(max_id: pagination_max_id)
api_v1_chat_conversation_accounts_chat_blocked_accounts_url pagination_params(max_id: pagination_max_id)
end
end
def prev_path
unless paginated_blocks.empty?
api_v1_chat_conversation_accounts_blocked_accounts_url pagination_params(since_id: pagination_since_id)
api_v1_chat_conversation_accounts_blocked_chat_accounts_url pagination_params(since_id: pagination_since_id)
end
end

@ -1,11 +1,11 @@
# frozen_string_literal: true
class Api::V1::ChatConversationAccounts::MutedAccountsController < Api::BaseController
class Api::V1::ChatConversationAccounts::MutedChatAccountsController < Api::BaseController
before_action -> { doorkeeper_authorize! :follow, :'read:mutes' }
before_action :require_user!
after_action :insert_pagination_headers
def index
def show
@accounts = load_accounts
render json: @accounts, each_serializer: REST::AccountSerializer
end
@ -32,13 +32,13 @@ class Api::V1::ChatConversationAccounts::MutedAccountsController < Api::BaseCont
def next_path
if records_continue?
api_v1_chat_conversation_accounts_muted_accounts_url pagination_params(max_id: pagination_max_id)
api_v1_chat_conversation_accounts_muted_chat_accounts_url pagination_params(max_id: pagination_max_id)
end
end
def prev_path
unless paginated_mutes.empty?
api_v1_chat_conversation_accounts_muted_accounts_url pagination_params(since_id: pagination_since_id)
api_v1_chat_conversation_accounts_muted_chat_accounts_url pagination_params(since_id: pagination_since_id)
end
end

@ -1,32 +1,36 @@
# frozen_string_literal: true
class Api::V1::ChatConversationAccountsController < Api::BaseController
before_action -> { authorize_if_got_token! :read, :'read:chats' }, except: [:create, :follow, :unfollow, :block, :unblock, :mute, :unmute]
before_action -> { doorkeeper_authorize! :write, :'write:chats' }, only: [:create]
before_action -> { authorize_if_got_token! :read, :'read:chats' }
before_action -> { doorkeeper_authorize! :write, :'write:chats' }
before_action :require_user!
before_action :set_account, except: [:create]
before_action :set_account
def show
def is_messenger_blocked
#
end
def block
def is_messenger_muted
#
end
def block_messenger
BlockMessengerService.new.call(current_user.account, @account)
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships
end
def mute
MuteMessengerService.new.call(current_user.account, @account, notifications: truthy_param?(:notifications))
def mute_messenger
MuteMessengerService.new.call(current_user.account, @account)
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships
end
def unblock
def unblock_messenger
UnblockMessengerService.new.call(current_user.account, @account)
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships
end
def unmute
def unmute_messenger
UnmuteMessegerService.new.call(current_user.account, @account)
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships
end
@ -34,19 +38,15 @@ class Api::V1::ChatConversationAccountsController < Api::BaseController
private
def set_account
# @account = Account.find(params[:id])
@account = Account.find(params[:id])
end
# def relationships(**options)
# AccountRelationshipsPresenter.new([@account.id], current_user.account_id, options)
# end
def check_account_suspension
gone if @account.suspended?
end
# def account_params
# params.permit(:username, :email, :password, :agreement, :locale)
# end
def relationships(**options)
AccountRelationshipsPresenter.new([@account.id], current_user.account_id, options)
end
end

@ -17,9 +17,9 @@ class Api::V1::ChatConversations::ApprovedConversationsController < Api::BaseCon
end
def unread_count
# : todo : make is_unread into unread_count then count
# count = ChatConversationAccount.where(account: current_account, is_hidden: false, is_approved: true, unread_count: true).count
render json: 1
unreads = ChatConversationAccount.where(account: current_account, is_hidden: false, is_approved: true).where('unread_count > 0')
sum = unreads.sum('unread_count')
render json: sum.to_i
end
private

@ -17,6 +17,7 @@ class Api::V1::ChatMessagesController < Api::BaseController
# : todo :
# check if blocked
# update unread_count++ if offline
@chat_conversation_recipients.each do |account|
payload = InlineRenderer.render(@chat, account, :chat_message)

@ -0,0 +1,340 @@
import api, { getLinks } from '../api'
import { importFetchedAccounts } from './importer'
import { me } from '../initial_state'
//
export const CHAT_MESSENGER_BLOCKS_FETCH_REQUEST = 'CHAT_MESSENGER_BLOCKS_FETCH_REQUEST'
export const CHAT_MESSENGER_BLOCKS_FETCH_SUCCESS = 'CHAT_MESSENGER_BLOCKS_FETCH_SUCCESS'
export const CHAT_MESSENGER_BLOCKS_FETCH_FAIL = 'CHAT_MESSENGER_BLOCKS_FETCH_FAIL'
export const CHAT_MESSENGER_BLOCKS_EXPAND_REQUEST = 'CHAT_MESSENGER_BLOCKS_EXPAND_REQUEST'
export const CHAT_MESSENGER_BLOCKS_EXPAND_SUCCESS = 'CHAT_MESSENGER_BLOCKS_EXPAND_SUCCESS'
export const CHAT_MESSENGER_BLOCKS_EXPAND_FAIL = 'CHAT_MESSENGER_BLOCKS_EXPAND_FAIL'
export const BLOCK_CHAT_MESSAGER_REQUEST = 'BLOCK_CHAT_MESSAGER_REQUEST'
export const BLOCK_CHAT_MESSAGER_SUCCESS = 'BLOCK_CHAT_MESSAGER_SUCCESS'
export const BLOCK_CHAT_MESSAGER_FAIL = 'BLOCK_CHAT_MESSAGER_FAIL'
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 CHAT_MESSENGER_MUTES_FETCH_REQUEST = 'CHAT_MESSENGER_MUTES_FETCH_REQUEST'
export const CHAT_MESSENGER_MUTES_FETCH_SUCCESS = 'CHAT_MESSENGER_MUTES_FETCH_SUCCESS'
export const CHAT_MESSENGER_MUTES_FETCH_FAIL = 'CHAT_MESSENGER_MUTES_FETCH_FAIL'
export const CHAT_MESSENGER_MUTES_EXPAND_REQUEST = 'CHAT_MESSENGER_MUTES_EXPAND_REQUEST'
export const CHAT_MESSENGER_MUTES_EXPAND_SUCCESS = 'CHAT_MESSENGER_MUTES_EXPAND_SUCCESS'
export const CHAT_MESSENGER_MUTES_EXPAND_FAIL = 'CHAT_MESSENGER_MUTES_EXPAND_FAIL'
export const MUTE_CHAT_MESSAGER_REQUEST = 'MUTE_CHAT_MESSAGER_REQUEST'
export const MUTE_CHAT_MESSAGER_SUCCESS = 'MUTE_CHAT_MESSAGER_SUCCESS'
export const MUTE_CHAT_MESSAGER_FAIL = 'MUTE_CHAT_MESSAGER_FAIL'
export const UNMUTE_CHAT_MESSAGER_REQUEST = 'UNMUTE_CHAT_MESSAGER_REQUEST'
export const UNMUTE_CHAT_MESSAGER_SUCCESS = 'UNMUTE_CHAT_MESSAGER_SUCCESS'
export const UNMUTE_CHAT_MESSAGER_FAIL = 'UNMUTE_CHAT_MESSAGER_FAIL'
export const IS_CHAT_MESSENGER_MUTED_SUCCESS = 'IS_CHAT_MESSENGER_MUTED_SUCCESS'
/**
*
*/
export const blockChatMessenger = (accountId) => (dispatch, getState) => {
if (!me || !accountId) return
dispatch(blockChatMessengerRequest(accountId))
api(getState).post(`/api/v1/chat_conversation_accounts/${accountId}/block_messenger`).then((response) => {
dispatch(blockChatMessengerSuccess())
}).catch((error) => {
dispatch(blockChatMessengerFail(accountId, error))
})
}
const blockChatMessengerRequest = (accountId) => ({
type: BLOCK_CHAT_MESSAGER_REQUEST,
accountId,
})
const blockChatMessengerSuccess = () => ({
type: BLOCK_CHAT_MESSAGER_SUCCESS,
showToast: true,
})
const blockChatMessengerFail = (accountId, error) => ({
type: BLOCK_CHAT_MESSAGER_FAIL,
showToast: true,
accountId,
error,
})
/**
*
*/
export const unblockChatMessenger = (accountId) => (dispatch, getState) => {
if (!me || !accountId) return
dispatch(unblockChatMessengerRequest(accountId))
api(getState).post(`/api/v1/chat_conversation_accounts/${accountId}/unblock_messenger`).then((response) => {
dispatch(unblockChatMessengerSuccess())
}).catch((error) => {
dispatch(unblockChatMessengerFail(accountId, error))
})
}
const unblockChatMessengerRequest = (accountId) => ({
type: UNBLOCK_CHAT_MESSAGER_REQUEST,
accountId,
})
const unblockChatMessengerSuccess = () => ({
type: UNBLOCK_CHAT_MESSAGER_REQUEST,
showToast: true,
})
const unblockChatMessengerFail = (accountId, error) => ({
type: UNBLOCK_CHAT_MESSAGER_REQUEST,
showToast: true,
accountId,
error,
})
/**
* @description Check if a chat messenger is blocked by the current user account.
* @param {String} accountId
*/
export const isChatMessengerBlocked = (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))
})
}
const isChatMessengerBlockedSuccess = (data) => ({
type: IS_CHAT_MESSENGER_BLOCKED_SUCCESS,
data,
})
/**
*
*/
export const fetchChatMessengerBlocks = () => (dispatch, getState) => {
if (!me) return
dispatch(fetchChatMessengerBlocksRequest())
api(getState).get('/api/v1/chat_conversation_accounts/blocked_chat_accounts').then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next')
dispatch(importFetchedAccounts(response.data))
dispatch(fetchChatMessengerBlocksSuccess(response.data, next ? next.uri : null))
}).catch(error => dispatch(fetchChatMessengerBlocksFail(error)))
}
export const fetchChatMessengerBlocksRequest = () => ({
type: CHAT_MESSENGER_BLOCKS_FETCH_REQUEST,
})
export const fetchChatMessengerBlocksSuccess = (accounts, next) => ({
type: CHAT_MESSENGER_BLOCKS_FETCH_SUCCESS,
accounts,
next,
})
export const fetchChatMessengerBlocksFail = (error) => ({
type: CHAT_MESSENGER_BLOCKS_FETCH_FAIL,
showToast: true,
error,
})
/**
*
*/
export const expandChatMessengerBlocks = () => (dispatch, getState) => {
if (!me) return
const url = getState().getIn(['user_lists', 'chat_blocks', me, 'next'])
const isLoading = getState().getIn(['user_lists', 'chat_blocks', me, 'isLoading'])
if (url === null || isLoading) return
dispatch(expandChatMessengerBlocksRequest())
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next')
dispatch(importFetchedAccounts(response.data))
dispatch(expandChatMessengerBlocksSuccess(response.data, next ? next.uri : null))
}).catch(error => dispatch(expandChatMessengerBlocksFail(error)))
}
export const expandChatMessengerBlocksRequest = () => ({
type: CHAT_MESSENGER_BLOCKS_EXPAND_REQUEST,
})
export const expandChatMessengerBlocksSuccess = (accounts, next) => ({
type: CHAT_MESSENGER_BLOCKS_EXPAND_SUCCESS,
accounts,
next,
})
export const expandChatMessengerBlocksFail = (error) => ({
type: CHAT_MESSENGER_BLOCKS_EXPAND_FAIL,
error,
})
//
/**
*
*/
export const muteChatMessenger = (accountId) => (dispatch, getState) => {
if (!me || !accountId) return
dispatch(muteChatMessengerRequest(accountId))
api(getState).post(`/api/v1/chat_conversation_accounts/${accountId}/mute_messenger`).then((response) => {
dispatch(muteChatMessengerSuccess())
}).catch((error) => {
dispatch(muteChatMessengerFail(accountId, error))
})
}
const muteChatMessengerRequest = (accountId) => ({
type: MUTE_CHAT_MESSAGER_REQUEST,
accountId,
})
const muteChatMessengerSuccess = () => ({
type: MUTE_CHAT_MESSAGER_SUCCESS,
showToast: true,
})
const muteChatMessengerFail = (accountId, error) => ({
type: MUTE_CHAT_MESSAGER_FAIL,
showToast: true,
accountId,
error,
})
/**
*
*/
export const unmuteChatMessenger = (accountId) => (dispatch, getState) => {
if (!me || !accountId) return
dispatch(unmuteChatMessengerRequest(accountId))
api(getState).post(`/api/v1/chat_conversation_accounts/${accountId}/unmute_messenger`).then((response) => {
dispatch(unmuteChatMessengerSuccess())
}).catch((error) => {
dispatch(unmuteChatMessengerFail(accountId, error))
})
}
const unmuteChatMessengerRequest = (accountId) => ({
type: UNMUTE_CHAT_MESSAGER_REQUEST,
accountId,
})
const unmuteChatMessengerSuccess = () => ({
type: UNMUTE_CHAT_MESSAGER_REQUEST,
showToast: true,
})
const unmuteChatMessengerFail = (accountId, error) => ({
type: UNMUTE_CHAT_MESSAGER_REQUEST,
showToast: true,
accountId,
error,
})
/**
* @description Check if a chat messenger is muted by the current user account.
* @param {String} accountId
*/
export const isChatMessengerMuted = (accountId) => (dispatch, getState) => {
if (!me || !accountId) return
api(getState).post(`/api/v1/chat_conversation_accounts/${accountId}/is_messenger_muted`).then((response) => {
dispatch(isChatMessengerMutedSuccess(response.data))
})
}
const isChatMessengerMutedSuccess = (data) => ({
type: IS_CHAT_MESSENGER_MUTED_SUCCESS,
data,
})
/**
*
*/
export const fetchChatMessengerMutes = () => (dispatch, getState) => {
if (!me) return
dispatch(fetchChatMessengerMutesRequest())
api(getState).get('/api/v1/chat_conversation_accounts/muted_chat_accounts').then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next')
dispatch(importFetchedAccounts(response.data))
dispatch(fetchChatMessengerMutesSuccess(response.data, next ? next.uri : null))
}).catch(error => dispatch(fetchChatMessengerMutesFail(error)))
}
export const fetchChatMessengerMutesRequest = () => ({
type: CHAT_MESSENGER_MUTES_FETCH_REQUEST,
})
export const fetchChatMessengerMutesSuccess = (accounts, next) => ({
type: CHAT_MESSENGER_MUTES_FETCH_SUCCESS,
accounts,
next,
})
export const fetchChatMessengerMutesFail = (error) => ({
type: CHAT_MESSENGER_MUTES_FETCH_FAIL,
showToast: true,
error,
})
/**
*
*/
export const expandChatMessengerMutes = () => (dispatch, getState) => {
if (!me) return
const url = getState().getIn(['user_lists', 'chat_mutes', me, 'next'])
const isLoading = getState().getIn(['user_lists', 'chat_mutes', me, 'isLoading'])
if (url === null || isLoading) return
dispatch(expandChatMessengerMutesRequest())
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next')
dispatch(importFetchedAccounts(response.data))
dispatch(expandChatMessengerMutesSuccess(response.data, next ? next.uri : null))
}).catch(error => dispatch(expandChatMessengerMutesFail(error)))
}
export const expandChatMessengerMutesRequest = () => ({
type: CHAT_MESSENGER_MUTES_EXPAND_REQUEST,
})
export const expandChatMessengerMutesSuccess = (accounts, next) => ({
type: CHAT_MESSENGER_MUTES_EXPAND_SUCCESS,
accounts,
next,
})
export const expandChatMessengerMutesFail = (error) => ({
type: CHAT_MESSENGER_MUTES_EXPAND_FAIL,
error,
})

@ -1,5 +1,4 @@
import api, { getLinks } from '../api'
import { fetchRelationships } from './accounts'
import { importFetchedAccounts } from './importer'
import { me } from '../initial_state'
@ -27,42 +26,6 @@ export const CHAT_CONVERSATIONS_DELETE_FAIL = 'CHAT_CONVERSATIONS_DELETE_FAIL
//
export const CHAT_CONVERSATION_BLOCKS_FETCH_REQUEST = 'CHAT_CONVERSATION_BLOCKS_FETCH_REQUEST'
export const CHAT_CONVERSATION_BLOCKS_FETCH_SUCCESS = 'CHAT_CONVERSATION_BLOCKS_FETCH_SUCCESS'
export const CHAT_CONVERSATION_BLOCKS_FETCH_FAIL = 'CHAT_CONVERSATION_BLOCKS_FETCH_FAIL'
export const CHAT_CONVERSATION_BLOCKS_EXPAND_REQUEST = 'CHAT_CONVERSATION_BLOCKS_EXPAND_REQUEST'
export const CHAT_CONVERSATION_BLOCKS_EXPAND_SUCCESS = 'CHAT_CONVERSATION_BLOCKS_EXPAND_SUCCESS'
export const CHAT_CONVERSATION_BLOCKS_EXPAND_FAIL = 'CHAT_CONVERSATION_BLOCKS_EXPAND_FAIL'
export const BLOCK_MESSAGER_REQUEST = 'BLOCK_MESSAGER_REQUEST'
export const BLOCK_MESSAGER_SUCCESS = 'BLOCK_MESSAGER_SUCCESS'
export const BLOCK_MESSAGER_FAIL = 'BLOCK_MESSAGER_FAIL'
export const UNBLOCK_MESSAGER_REQUEST = 'UNBLOCK_MESSAGER_REQUEST'
export const UNBLOCK_MESSAGER_SUCCESS = 'UNBLOCK_MESSAGER_SUCCESS'
export const UNBLOCK_MESSAGER_FAIL = 'UNBLOCK_MESSAGER_FAIL'
//
export const CHAT_CONVERSATION_MUTES_FETCH_REQUEST = 'CHAT_CONVERSATION_MUTES_FETCH_REQUEST'
export const CHAT_CONVERSATION_MUTES_FETCH_SUCCESS = 'CHAT_CONVERSATION_MUTES_FETCH_SUCCESS'
export const CHAT_CONVERSATION_MUTES_FETCH_FAIL = 'CHAT_CONVERSATION_MUTES_FETCH_FAIL'
export const CHAT_CONVERSATION_MUTES_EXPAND_REQUEST = 'CHAT_CONVERSATION_MUTES_EXPAND_REQUEST'
export const CHAT_CONVERSATION_MUTES_EXPAND_SUCCESS = 'CHAT_CONVERSATION_MUTES_EXPAND_SUCCESS'
export const CHAT_CONVERSATION_MUTES_EXPAND_FAIL = 'CHAT_CONVERSATION_MUTES_EXPAND_FAIL'
export const MUTE_MESSAGER_REQUEST = 'BLOCK_MESSAGER_REQUEST'
export const MUTE_MESSAGER_SUCCESS = 'BLOCK_MESSAGER_SUCCESS'
export const MUTE_MESSAGER_FAIL = 'BLOCK_MESSAGER_FAIL'
export const UNMUTE_MESSAGER_REQUEST = 'UNMUTE_MESSAGER_REQUEST'
export const UNMUTE_MESSAGER_SUCCESS = 'UNMUTE_MESSAGER_SUCCESS'
export const UNMUTE_MESSAGER_FAIL = 'UNMUTE_MESSAGER_FAIL'
//
export const CHAT_CONVERSATION_REQUESTED_COUNT_FETCH_SUCCESS = 'CHAT_CONVERSATION_REQUESTED_COUNT_FETCH_SUCCESS'
export const CHAT_CONVERSATIONS_REQUESTED_FETCH_REQUEST = 'CHAT_CONVERSATIONS_REQUESTED_FETCH_REQUEST'
@ -83,7 +46,7 @@ export const CHAT_CONVERSATION_DELETE_SUCCESS = 'CHAT_CONVERSATION_DELETE_SUCCES
export const CHAT_CONVERSATION_DELETE_FAIL = 'CHAT_CONVERSATION_DELETE_FAIL'
/**
*
* @description Fetch paginated active chat conversations, import accounts and set chat converations
*/
export const fetchChatConversations = () => (dispatch, getState) => {
if (!me) return
@ -91,17 +54,14 @@ export const fetchChatConversations = () => (dispatch, getState) => {
dispatch(fetchChatConversationsRequest())
api(getState).get('/api/v1/chat_conversations/approved_conversations').then((response) => {
console.log("chat_conversations response: ", response)
const next = getLinks(response).refs.find(link => link.rel === 'next')
const conversationsAccounts = [].concat.apply([], response.data.map((c) => c.other_accounts))
const conversationsChatMessages = response.data.map((c) => c.last_chat_message)
// const conversationsChatMessages = response.data.map((c) => c.last_chat_message)
dispatch(importFetchedAccounts(conversationsAccounts))
// dispatch(importFetchedChatMessages(conversationsChatMessages))
dispatch(fetchChatConversationsSuccess(response.data, next ? next.uri : null))
}).catch((error) => {
console.log("fetchChatConversationsFail:", error)
dispatch(fetchChatConversationsFail(error))
})
}
@ -118,11 +78,12 @@ export const fetchChatConversationsSuccess = (chatConversations, next) => ({
export const fetchChatConversationsFail = (error) => ({
type: CHAT_CONVERSATIONS_APPROVED_FETCH_FAIL,
showToast: true,
error,
})
/**
*
* @description Expand paginated active chat conversations, import accounts and set chat converations
*/
export const expandChatConversations = () => (dispatch, getState) => {
if (!me) return
@ -137,12 +98,12 @@ export const expandChatConversations = () => (dispatch, getState) => {
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next')
const conversationsAccounts = [].concat.apply([], response.data.map((c) => c.other_accounts))
const conversationsChatMessages = response.data.map((c) => c.last_chat_message)
// const conversationsChatMessages = response.data.map((c) => c.last_chat_message)
dispatch(importFetchedAccounts(conversationsAccounts))
// dispatch(importFetchedChatMessages(conversationsChatMessages))
dispatch(expandChatConversationsSuccess(response.data, next ? next.uri : null))
}).catch(error => dispatch(expandChatConversationsFail(error)))
}).catch((error) => dispatch(expandChatConversationsFail(error)))
}
export const expandChatConversationsRequest = () => ({
@ -157,11 +118,12 @@ export const expandChatConversationsSuccess = (chatConversations, next) => ({
export const expandChatConversationsFail = (error) => ({
type: CHAT_CONVERSATIONS_APPROVED_EXPAND_SUCCESS,
showToast: true,
error,
})
/**
*
* @description Fetch paginated requested chat conversations, import accounts and set chat converations
*/
export const fetchChatConversationRequested = () => (dispatch, getState) => {
if (!me) return
@ -171,13 +133,12 @@ export const fetchChatConversationRequested = () => (dispatch, getState) => {
api(getState).get('/api/v1/chat_conversations/requested_conversations').then((response) => {
const next = getLinks(response).refs.find(link => link.rel === 'next')
const conversationsAccounts = [].concat.apply([], response.data.map((c) => c.other_accounts))
const conversationsChatMessages = response.data.map((c) => c.last_chat_message)
// const conversationsChatMessages = response.data.map((c) => c.last_chat_message)
dispatch(importFetchedAccounts(conversationsAccounts))
// dispatch(importFetchedChatMessages(conversationsChatMessages))
dispatch(fetchChatConversationRequestedSuccess(response.data, next ? next.uri : null))
}).catch((error) => {
console.log("error:", error)
dispatch(fetchChatConversationRequestedFail(error))
})
}
@ -194,11 +155,12 @@ export const fetchChatConversationRequestedSuccess = (chatConversations, next) =
export const fetchChatConversationRequestedFail = (error) => ({
type: CHAT_CONVERSATIONS_REQUESTED_FETCH_FAIL,
showToast: true,
error,
})
/**
*
* @description Expand paginated requested chat conversations, import accounts and set chat converations
*/
export const expandChatConversationRequested = () => (dispatch, getState) => {
if (!me) return
@ -213,7 +175,7 @@ export const expandChatConversationRequested = () => (dispatch, getState) => {
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next')
const conversationsAccounts = [].concat.apply([], response.data.map((c) => c.other_accounts))
const conversationsChatMessages = response.data.map((c) => c.last_chat_message)
// const conversationsChatMessages = response.data.map((c) => c.last_chat_message)
dispatch(importFetchedAccounts(conversationsAccounts))
// dispatch(importFetchedChatMessages(conversationsChatMessages))
@ -233,11 +195,13 @@ export const expandChatConversationRequestedSuccess = (chatConversations, next)
export const expandChatConversationRequestedFail = (error) => ({
type: CHAT_CONVERSATIONS_REQUESTED_EXPAND_FAIL,
showToast: true,
error,
})
/**
*
* @description Create a chat conversation with given accountId. May fail because of blocks.
* @param {String} accountId
*/
export const createChatConversation = (accountId) => (dispatch, getState) => {
if (!me || !accountId) return
@ -257,18 +221,22 @@ export const createChatConversationRequest = () => ({
export const createChatConversationSuccess = (chatConversation) => ({
type: CHAT_CONVERSATIONS_CREATE_SUCCESS,
showToast: true,
chatConversation,
})
export const createChatConversationFail = (error) => ({
type: CHAT_CONVERSATIONS_CREATE_FAIL,
showToast: true,
error,
})
/**
*
* @description Delete a chat conversation with given chatConversationId.
* @param {String} chatConversationId
*/
export const deleteChatConversation = (chatConversationId) => (dispatch, getState) => {
// : todo :
if (!me || !chatConversationId) return
dispatch(deleteChatConversationRequest(conversationId))
@ -295,136 +263,6 @@ export const deleteChatConversationFail = (error) => ({
error,
})
/**
*
*/
export const blockMessenger = (accountId) => (dispatch, getState) => {
if (!accountId) return
dispatch(blockMessengerRequest(accountId))
api(getState).post(`/api/v1/messages/accounts/${accountId}/block`).then((response) => {
dispatch(blockMessengerSuccess(response.data))
}).catch((error) => {
dispatch(blockMessengerFail(accountId, error))
})
}
const blockMessengerRequest = (accountId) => ({
type: BLOCK_MESSAGER_REQUEST,
accountId,
})
const blockMessengerSuccess = (data) => ({
type: BLOCK_MESSAGER_REQUEST,
data,
})
const blockMessengerFail = (accountId, error) => ({
type: BLOCK_MESSAGER_REQUEST,
accountId,
error,
})
/**
*
*/
export const unblockMessenger = (accountId) => (dispatch, getState) => {
if (!accountId) return
dispatch(unblockMessengerRequest(accountId))
api(getState).post(`/api/v1/messages/accounts/${accountId}/unblock`).then((response) => {
dispatch(unblockMessengerSuccess(response.data))
}).catch((error) => {
dispatch(unblockMessengerFail(accountId, error))
})
}
const unblockMessengerRequest = (accountId) => ({
type: UNBLOCK_MESSAGER_REQUEST,
accountId,
})
const unblockMessengerSuccess = (data) => ({
type: UNBLOCK_MESSAGER_REQUEST,
data,
})
const unblockMessengerFail = (accountId, error) => ({
type: UNBLOCK_MESSAGER_REQUEST,
accountId,
error,
})
/**
*
*/
export const fetchBlocks = () => (dispatch, getState) => {
if (!me) return
dispatch(fetchBlocksRequest())
api(getState).get('/api/v1/blocks').then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next')
dispatch(importFetchedAccounts(response.data))
dispatch(fetchBlocksSuccess(response.data, next ? next.uri : null))
dispatch(fetchRelationships(response.data.map(item => item.id)))
}).catch(error => dispatch(fetchBlocksFail(error)))
}
// export const fetchBlocksRequest = () => ({
// type: BLOCKS_FETCH_REQUEST,
// })
// export const fetchBlocksSuccess = (accounts, next) => ({
// type: BLOCKS_FETCH_SUCCESS,
// accounts,
// next,
// })
// export const fetchBlocksFail = (error) => ({
// type: BLOCKS_FETCH_FAIL,
// error,
// })
/**
*
*/
export const expandBlocks = () => (dispatch, getState) => {
if (!me) return
const url = getState().getIn(['user_lists', 'blocks', me, 'next'])
const isLoading = getState().getIn(['user_lists', 'blocks', me, 'isLoading'])
if (url === null || isLoading) return
dispatch(expandBlocksRequest())
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next')
dispatch(importFetchedAccounts(response.data))
dispatch(expandBlocksSuccess(response.data, next ? next.uri : null))
dispatch(fetchRelationships(response.data.map(item => item.id)))
}).catch(error => dispatch(expandBlocksFail(error)))
}
// export const expandBlocksRequest = () => ({
// type: BLOCKS_EXPAND_REQUEST,
// })
// export const expandBlocksSuccess = (accounts, next) => ({
// type: BLOCKS_EXPAND_SUCCESS,
// accounts,
// next,
// })
// export const expandBlocksFail = (error) => ({
// type: BLOCKS_EXPAND_FAIL,
// error,
// })
/**
*
*/

@ -12,6 +12,10 @@ export const CHAT_MESSAGES_DELETE_REQUEST = 'CHAT_MESSAGES_DELETE_REQUEST'
export const CHAT_MESSAGES_DELETE_SUCCESS = 'CHAT_MESSAGES_DELETE_SUCCESS'
export const CHAT_MESSAGES_DELETE_FAIL = 'CHAT_MESSAGES_DELETE_FAIL'
export const CHAT_MESSAGES_PURGE_REQUEST = 'CHAT_MESSAGES_PURGE_REQUEST'
export const CHAT_MESSAGES_PURGE_SUCCESS = 'CHAT_MESSAGES_PURGE_SUCCESS'
export const CHAT_MESSAGES_PURGE_FAIL = 'CHAT_MESSAGES_PURGE_FAIL'
/**
*
*/
@ -85,4 +89,35 @@ const deleteChatMessageFail = (error) => ({
type: CHAT_MESSAGES_DELETE_FAIL,
showToast: true,
error,
})
/**
*
*/
export const purgeChatMessages = (chatConversationId) => (dispatch, getState) => {
if (!me || !chatConversationId) return
dispatch(deleteChatMessagesRequest(chatConversationId))
api(getState).delete(`/api/v1/chat_conversations/${chatConversationId}/messages/destroy_all`).then((response) => {
dispatch(deleteChatMessagesSuccess(response.data))
}).catch((error) => {
dispatch(deleteChatMessagesFail(error))
})
}
const deleteChatMessagesRequest = () => ({
type: CHAT_MESSAGES_PURGE_REQUEST,
})
const deleteChatMessagesSuccess = (chatConversationId) => ({
type: CHAT_MESSAGES_PURGE_SUCCESS,
chatConversationId,
showToast: true,
})
const deleteChatMessagesFail = (error) => ({
type: CHAT_MESSAGES_PURGE_FAIL,
showToast: true,
error,
})

@ -5,10 +5,10 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import { openModal } from '../../actions/modal'
import { cancelReplyCompose } from '../../actions/compose'
import ComposeFormSubmitButton from '../../features/compose/components/compose_form_submit_button'
import TimelineComposeBlock from '../timeline_compose_block'
import Block from '../block'
import Heading from '../heading'
import Text from '../text'
import Button from '../button'
class ComposeModal extends ImmutablePureComponent {
@ -51,27 +51,23 @@ class ComposeModal extends ImmutablePureComponent {
return (
<div style={{width: '512px'}} className={[_s.d, _s.modal].join(' ')}>
<Block>
<div className={[_s.d, _s.flexRow, _s.aiCenter, _s.jcCenter, _s.borderBottom1PX, _s.borderColorSecondary, _s.h53PX, _s.px15].join(' ')}>
<Button
backgroundColor='none'
title={intl.formatMessage(messages.close)}
onClick={this.onClickClose}
color='secondary'
icon='close'
iconSize='10px'
/>
<div className={[_s.d, _s.flexRow, _s.aiCenter, _s.jcCenter, _s.borderBottom1PX, _s.borderColorSecondary, _s.h53PX, _s.pl10, _s.pr15].join(' ')}>
<div className={[_s.d, _s.w115PX, _s.aiStart, _s.jcCenter, _s.mrAuto].join(' ')}>
<Button
backgroundColor='none'
title={intl.formatMessage(messages.close)}
onClick={this.onClickClose}
color='secondary'
icon='close'
iconSize='10px'
/>
</div>
<Heading size='h2'>
{intl.formatMessage(title)}
</Heading>
<Button
backgroundColor='none'
title={intl.formatMessage(messages.close)}
className={_s.mlAuto}
onClick={this.onHandleSubmit}
color='secondary'
>
<Text>Post</Text>
</Button>
<div className={[_s.d, _s.w115PX, _s.aiEnd, _s.jcCenter, _s.mlAuto].join(' ')}>
<ComposeFormSubmitButton type='header' />
</div>
</div>
<div className={[_s.d].join(' ')}>
<TimelineComposeBlock isModal />
@ -92,7 +88,6 @@ const messages = defineMessages({
const mapStateToProps = (state) => {
const status = state.getIn(['statuses', state.getIn(['compose', 'id'])])
return {
composeText: state.getIn(['compose', 'text']),
isEditing: !!status,

@ -5,6 +5,14 @@ import ImmutablePureComponent from 'react-immutable-pure-component'
import { connect } from 'react-redux'
import { closePopover } from '../../actions/popover'
import { openModal } from '../../actions/modal'
import {
isChatMessengerBlocked,
isChatMessengerMuted,
blockChatMessenger,
unblockChatMessenger,
muteChatMessenger,
unmuteChatMessenger,
} from '../../actions/chat_conversation_accounts'
import { MODAL_PRO_UPGRADE } from '../../constants'
import { me } from '../../initial_state'
import { makeGetChatConversation } from '../../selectors'
@ -14,24 +22,39 @@ import List from '../list'
class ChatConversationOptionsPopover extends ImmutablePureComponent {
handleOnBlock = () => {
//
handleOnHide = () => {
this.props.onHide()
this.handleOnClosePopover()
}
handleOnHide = () => {
handleOnBlock = () => {
this.props.onBlock()
this.handleOnClosePopover()
}
handleOnUnblock = () => {
this.props.onUnblock()
this.handleOnClosePopover()
}
handleOnMute = () => {
this.props.onMute()
this.handleOnClosePopover()
}
handleOnUnmute = () => {
this.props.onUnute()
this.handleOnClosePopover()
}
handleOnPurge = () => {
if (!this.props.isPro) {
this.props.openProUpgradeModal()
} else {
//
this.props.onPurge()
}
this.handleOnClosePopover()
}
handleOnClosePopover = () => {

@ -92,6 +92,7 @@ class DeckSidebar extends ImmutablePureComponent {
<Divider isSmall />
<NavigationBarButton attrTitle='Chat' icon='chat' to='/messages' />
<NavigationBarButton attrTitle='Dark/Muted/Light/White Mode' icon='light-bulb' onClick={this.handleOnClickLightBulb} />
<button

@ -6,7 +6,11 @@ import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes'
import debounce from 'lodash.debounce'
import { me } from '../initial_state'
import { fetchBlocks, expandBlocks } from '../actions/blocks'
import {
fetchChatMessengerBlocks,
expandChatMessengerBlocks,
unblockChatMessenger,
} from '../actions/chat_conversation_accounts'
import Account from '../components/account'
import Block from '../components/block'
import BlockHeading from '../components/block_heading'
@ -14,7 +18,7 @@ import Divider from '../components/divider'
import ScrollableList from '../components/scrollable_list'
import AccountPlaceholder from '../components/placeholder/account_placeholder'
class MessagesBlockedAccounts extends ImmutablePureComponent {
class ChatConversationBlockedAccounts extends ImmutablePureComponent {
componentDidMount() {
this.props.onFetchBlocks()
@ -40,7 +44,7 @@ class MessagesBlockedAccounts extends ImmutablePureComponent {
<BlockHeading title={intl.formatMessage(messages.blocks)} />
</div>
<ScrollableList
scrollKey='blocked_accounts'
scrollKey='chat_blocked_accounts'
onLoadMore={this.handleLoadMore}
hasMore={hasMore}
isLoading={isLoading}
@ -55,6 +59,9 @@ class MessagesBlockedAccounts extends ImmutablePureComponent {
key={`blocked-accounts-${id}`}
id={id}
compact
actionIcon='subtract'
onActionClick={() => this.props.onRemove(id)}
actionTitle='Remove'
/>
))
}
@ -66,22 +73,23 @@ class MessagesBlockedAccounts extends ImmutablePureComponent {
}
const messages = defineMessages({
empty: { id: 'empty_column.blocks', defaultMessage: 'You haven\'t blocked any users yet.' },
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
empty: { id: 'empty_column.chat_blocks', defaultMessage: 'You haven\'t blocked any chat users yet.' },
blocks: { id: 'navigation_bar.chat_blocks', defaultMessage: 'Blocked chat users' },
})
const mapStateToProps = (state) => ({
accountIds: state.getIn(['user_lists', 'blocks', me, 'items']),
hasMore: !!state.getIn(['user_lists', 'blocks', me, 'next']),
isLoading: state.getIn(['user_lists', 'blocks', me, 'isLoading']),
accountIds: state.getIn(['user_lists', 'chat_blocks', me, 'items']),
hasMore: !!state.getIn(['user_lists', 'chat_blocks', me, 'next']),
isLoading: state.getIn(['user_lists', 'chat_blocks', me, 'isLoading']),
})
const mapDispatchToProps = (dispatch) => ({
onFetchBlocks: () => dispatch(fetchBlocks()),
onExpandBlocks: () => dispatch(expandBlocks()),
onFetchBlocks: () => dispatch(fetchChatMessengerBlocks()),
onExpandBlocks: () => dispatch(expandChatMessengerBlocks()),
onRemove: (accountId) => dispatch(unblockChatMessenger(accountId)),
})
MessagesBlockedAccounts.propTypes = {
ChatConversationBlockedAccounts.propTypes = {
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
intl: PropTypes.object.isRequired,
@ -90,4 +98,4 @@ MessagesBlockedAccounts.propTypes = {
onFetchBlocks: PropTypes.func.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(MessagesBlockedAccounts))
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ChatConversationBlockedAccounts))

@ -6,13 +6,17 @@ import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes'
import debounce from 'lodash.debounce'
import { me } from '../initial_state'
import { fetchMutes, expandMutes } from '../actions/mutes'
import {
fetchChatMessengerMutes,
expandChatMessengerMutes,
unmuteChatMessenger,
} from '../actions/chat_conversation_accounts'
import Account from '../components/account'
import Block from '../components/block'
import BlockHeading from '../components/block_heading'
import ScrollableList from '../components/scrollable_list'
class MessagesMutedAccounts extends ImmutablePureComponent {
class ChatConversationMutedAccounts extends ImmutablePureComponent {
componentWillMount() {
this.props.onFetchMutes()
@ -32,14 +36,14 @@ class MessagesMutedAccounts extends ImmutablePureComponent {
return (
<div className={[_s.d, _s.w100PC, _s.boxShadowNone].join(' ')}>
<div className={[_s.d, _s.h60PX, _s.w100PC, _s.px10, _s.py10, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
<BlockHeading title={<FormattedMessage id='navigation_bar.mutes' defaultMessage='Muted users' />} />
<BlockHeading title={<FormattedMessage id='navigation_bar.chat_mutes' defaultMessage='Muted chat users' />} />
</div>
<ScrollableList
scrollKey='mutes'
scrollKey='chat_muted_accounts'
onLoadMore={this.handleLoadMore}
hasMore={hasMore}
isLoading={isLoading}
emptyMessage={<FormattedMessage id='empty_column.mutes' defaultMessage="You haven't muted any users yet." />}
emptyMessage={<FormattedMessage id='empty_column.chat_mutes' defaultMessage="You haven't muted any chat users yet." />}
>
{
accountIds && accountIds.map((id) =>
@ -47,6 +51,9 @@ class MessagesMutedAccounts extends ImmutablePureComponent {
key={`mutes-${id}`}
id={id}
compact
actionIcon='subtract'
onActionClick={() => this.props.onRemove(id)}
actionTitle='Remove'
/>
)
}
@ -58,17 +65,18 @@ class MessagesMutedAccounts extends ImmutablePureComponent {
}
const mapStateToProps = (state) => ({
accountIds: state.getIn(['user_lists', 'mutes', me, 'items']),
hasMore: !!state.getIn(['user_lists', 'mutes', me, 'next']),
isLoading: state.getIn(['user_lists', 'mutes', me, 'isLoading']),
accountIds: state.getIn(['user_lists', 'chat_mutes', me, 'items']),
hasMore: !!state.getIn(['user_lists', 'chat_mutes', me, 'next']),
isLoading: state.getIn(['user_lists', 'chat_mutes', me, 'isLoading']),
})
const mapDispatchToProps = (dispatch) => ({
onFetchMutes: () => dispatch(fetchMutes()),
onExpandMutes: () => dispatch(expandMutes()),
onFetchMutes: () => dispatch(fetchChatMessengerMutes()),
onExpandMutes: () => dispatch(expandChatMessengerMutes()),
onRemove: (accountId) => dispatch(unmuteChatMessenger(accountId)),
})
MessagesMutedAccounts.propTypes = {
ChatConversationMutedAccounts.propTypes = {
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
@ -76,4 +84,4 @@ MessagesMutedAccounts.propTypes = {
onFetchMutes: PropTypes.func.isRequired,
}
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(MessagesMutedAccounts))
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ChatConversationMutedAccounts))

@ -17,6 +17,7 @@ class ComposeExtraButton extends React.PureComponent {
buttonRef,
isLast,
small,
iconClassName,
} = this.props
const containerClasses = CX({
@ -42,7 +43,7 @@ class ComposeExtraButton extends React.PureComponent {
px10: 1,
})
const iconClasses = CX({
const iconClasses = CX(iconClassName, {
cSecondary: !active,
cWhite: active,
mr10: 1,
@ -89,6 +90,7 @@ ComposeExtraButton.propTypes = {
active: PropTypes.bool,
buttonRef: PropTypes.func,
small: PropTypes.bool,
iconClassName: PropTypes.string,
}
export default ComposeExtraButton

@ -43,10 +43,16 @@ class ComposeExtraButtonList extends React.PureComponent {
render() {
const { isMatch, edit, hidePro, isModal } = this.props
const {
isMatch,
edit,
hidePro,
isModal,
isStandalone,
} = this.props
const { height } = this.state
const small = height <= 660 || isModal
const small = (height <= 660 || isModal) && !isStandalone
const containerClasses = CX({
d: 1,
@ -84,6 +90,7 @@ ComposeExtraButtonList.propTypes = {
edit: PropTypes.bool,
isMatch: PropTypes.bool,
isModal: PropTypes.bool,
isStandalone: PropTypes.bool,
}
export default ComposeExtraButtonList

@ -28,6 +28,7 @@ import ExpiresPostButton from './expires_post_button'
import RichTextEditorButton from './rich_text_editor_button'
import StatusContainer from '../../../containers/status_container'
import StatusVisibilityButton from './status_visibility_button'
import MoreButton from './more_button'
import UploadButton from './media_upload_button'
import UploadForm from './upload_form'
import Input from '../../../components/input'
@ -82,6 +83,8 @@ class ComposeForm extends ImmutablePureComponent {
if (!this.form.contains(e.target)) {
this.handleClickOutside()
} else {
// : todo :
// if mobile go to /compose else openModal
if (!isStandalone && !isModalOpen && !shouldCondense) {
this.props.openComposeModal()
return false
@ -395,7 +398,7 @@ class ComposeForm extends ImmutablePureComponent {
{ !isModalOpen && <ComposeFormSubmitButton /> }
<ComposeExtraButtonList isMatch={isMatch} hidePro={hidePro} edit={edit} isModal={isModalOpen} />
<ComposeExtraButtonList isStandalone={isStandalone} isMatch={isMatch} hidePro={hidePro} edit={edit} isModal={isModalOpen} />
</div>
)
}
@ -413,6 +416,7 @@ class ComposeForm extends ImmutablePureComponent {
<UploadButton />
<EmojiPickerButton isMatch={isMatch} />
<PollButton />
<MoreButton />
<ComposeFormSubmitButton />
</div>
<div className={[_s.d, _s.posAbs, _s.z2, _s.left0, _s.right0, _s.bottom0, _s.top0].join(' ')} />

@ -12,6 +12,7 @@ class ComposeFormSubmitButton extends React.PureComponent {
active,
small,
disabledButton,
type,
} = this.props
const containerClasses = CX({
@ -72,7 +73,7 @@ class ComposeFormSubmitButton extends React.PureComponent {
// {intl.formatMessage(scheduledAt ? messages.schedulePost : edit ? messages.postEdit : messages.post)}
ComposeFormSubmitButton.propTypes = {
type: PropTypes.oneOf(['header', 'block', 'comment'])
}
export default ComposeFormSubmitButton

@ -32,6 +32,7 @@ class EmojiPickerButton extends React.PureComponent {
active={active && isMatch}
buttonRef={this.setButton}
small={small}
iconClassName={_s.cIconComposeEmoji}
/>
)
}

@ -40,6 +40,7 @@ class ExpiresPostButton extends React.PureComponent {
onClick={this.handleToggle}
small={small}
title={intl.formatMessage(messages.expires)}
iconClassName={_s.cIconComposeExpires}
/>
)
}

@ -42,6 +42,7 @@ class UploadButton extends ImmutablePureComponent {
onClick={this.handleClick}
small={small}
icon='media'
iconClassName={_s.cIconComposeMedia}
>
<label>
<span className={_s.displayNone}>{intl.formatMessage(messages.upload)}</span>

@ -0,0 +1,10 @@
import React from 'react'
import ComposeExtraButton from './compose_extra_button'
class MoreButton extends React.PureComponent {
render () {
return <ComposeExtraButton title='More' icon='more' iconClassName={_s.cTertiary} />
}
}
export default MoreButton

@ -30,6 +30,7 @@ class PollButton extends React.PureComponent {
icon='poll'
small={small}
active={active}
iconClassName={_s.cIconComposePoll}
/>
)
}

@ -28,6 +28,7 @@ class RichTextEditorButton extends React.PureComponent {
onClick={this.handleClick}
small={small}
active={active}
iconClassName={_s.cIconComposeRichText}
/>
)
}

@ -41,6 +41,7 @@ class SchedulePostButton extends React.PureComponent {
onClick={this.handleToggle}
small={small}
title={intl.formatMessage(messages.schedule_status)}
iconClassName={_s.cIconComposeSchedule}
/>
)
}

@ -22,6 +22,7 @@ class SpoilerButton extends React.PureComponent {
onClick={this.handleClick}
small={small}
active={active}
iconClassName={_s.cIconComposeSpoiler}
/>
)
}

@ -42,6 +42,7 @@ class StatusVisibilityButton extends React.PureComponent {
onClick={this.handleOnClick}
small={small}
buttonRef={this.setButton}
iconClassName={_s.cIconComposeSensitive}
/>
)
}

@ -114,7 +114,7 @@ class ChatMessagesComposeForm extends React.PureComponent {
disabled={disabled}
onClick={this.handleOnSendChatMessage}
>
<Text color='inherit' className={_s.px10}>Send</Text>
<Text color='inherit' weight='medium' className={_s.px10}>Send</Text>
</Button>
)

@ -130,7 +130,7 @@ class MessagesLayout extends React.PureComponent {
},
]}
>
<div className={[_s.d, _s.flexRow, _s.w100PC, _s.calcH53PX].join(' ')}>
<div className={[_s.d, _s.flexRow, _s.boxShadowNone, _s.w100PC, _s.calcH53PX].join(' ')}>
<ResponsiveClassesComponent
classNames={[_s.d, _s.flexShrink1, _s.flexGrow1].join(' ')}
classNamesSmall={[_s.d, _s.flexShrink1, _s.flexGrow1].join(' ')}
@ -159,7 +159,6 @@ class MessagesLayout extends React.PureComponent {
</Layout>
)
}
}
const mapStateToProps = (state) => {

@ -95,10 +95,10 @@ const reducers = {
status_revisions,
suggestions,
timelines,
// timeline_injections,
// toasts,
// user,
// user_lists,
timeline_injections,
toasts,
user,
user_lists,
}
export default combineReducers(reducers)

@ -7,12 +7,14 @@ import {
FOLLOWERS_FETCH_FAIL,
FOLLOWERS_EXPAND_REQUEST,
FOLLOWERS_EXPAND_FAIL,
FOLLOWING_FETCH_REQUEST,
FOLLOWING_FETCH_FAIL,
FOLLOWING_EXPAND_REQUEST,
FOLLOWING_FETCH_SUCCESS,
FOLLOWING_EXPAND_SUCCESS,
FOLLOWING_EXPAND_FAIL,
FOLLOW_REQUESTS_FETCH_REQUEST,
FOLLOW_REQUESTS_FETCH_FAIL,
FOLLOW_REQUESTS_EXPAND_REQUEST,
@ -29,6 +31,7 @@ import {
REPOSTS_EXPAND_REQUEST,
REPOSTS_EXPAND_SUCCESS,
REPOSTS_EXPAND_FAIL,
LIKES_FETCH_REQUEST,
LIKES_FETCH_SUCCESS,
LIKES_FETCH_FAIL,
@ -52,12 +55,28 @@ import {
MUTES_EXPAND_SUCCESS,
MUTES_EXPAND_FAIL,
} from '../actions/mutes'
import {
CHAT_MESSENGER_BLOCKS_FETCH_REQUEST,
CHAT_MESSENGER_BLOCKS_FETCH_SUCCESS,
CHAT_MESSENGER_BLOCKS_FETCH_FAIL,
CHAT_MESSENGER_BLOCKS_EXPAND_REQUEST,
CHAT_MESSENGER_BLOCKS_EXPAND_SUCCESS,
CHAT_MESSENGER_BLOCKS_EXPAND_FAIL,
CHAT_MESSENGER_MUTES_FETCH_REQUEST,
CHAT_MESSENGER_MUTES_FETCH_SUCCESS,
CHAT_MESSENGER_MUTES_FETCH_FAIL,
CHAT_MESSENGER_MUTES_EXPAND_REQUEST,
CHAT_MESSENGER_MUTES_EXPAND_SUCCESS,
CHAT_MESSENGER_MUTES_EXPAND_FAIL,
} from '../actions/chat_conversation_accounts'
import {
GROUP_MEMBERS_FETCH_SUCCESS,
GROUP_MEMBERS_EXPAND_SUCCESS,
GROUP_REMOVED_ACCOUNTS_FETCH_SUCCESS,
GROUP_REMOVED_ACCOUNTS_EXPAND_SUCCESS,
GROUP_REMOVED_ACCOUNTS_REMOVE_SUCCESS,
GROUP_JOIN_REQUESTS_FETCH_SUCCESS,
GROUP_JOIN_REQUESTS_EXPAND_SUCCESS,
GROUP_JOIN_REQUESTS_APPROVE_SUCCESS,
@ -73,6 +92,8 @@ const initialState = ImmutableMap({
follow_requests: ImmutableMap(),
blocks: ImmutableMap(),
mutes: ImmutableMap(),
chat_blocks: ImmutableMap(),
chat_mutes: ImmutableMap(),
groups: ImmutableMap(),
group_removed_accounts: ImmutableMap(),
group_join_requests: ImmutableMap(),
@ -210,6 +231,29 @@ export default function userLists(state = initialState, action) {
case GROUP_JOIN_REQUESTS_APPROVE_SUCCESS:
case GROUP_JOIN_REQUESTS_REJECT_SUCCESS:
return state.updateIn(['group_join_requests', action.groupId, 'items'], list => list.filterNot(item => item === action.accountId));
case CHAT_MESSENGER_BLOCKS_FETCH_REQUEST:
case CHAT_MESSENGER_BLOCKS_EXPAND_REQUEST:
return state.setIn(['chat_blocks', me, 'isLoading'], true)
case CHAT_MESSENGER_BLOCKS_FETCH_SUCCESS:
return normalizeList(state, 'chat_blocks', me, action.accounts, action.next)
case CHAT_MESSENGER_BLOCKS_EXPAND_SUCCESS:
return appendToList(state, 'chat_blocks', me, action.accounts, action.next)
case CHAT_MESSENGER_BLOCKS_FETCH_FAIL:
case CHAT_MESSENGER_BLOCKS_EXPAND_FAIL:
return setListFailed(state, 'chat_blocks', me)
case CHAT_MESSENGER_MUTES_FETCH_REQUEST:
case CHAT_MESSENGER_MUTES_EXPAND_REQUEST:
return state.setIn(['chat_mutes', me, 'isLoading'], true)
case CHAT_MESSENGER_MUTES_FETCH_SUCCESS:
return normalizeList(state, 'chat_mutes', me, action.accounts, action.next)
case CHAT_MESSENGER_MUTES_EXPAND_SUCCESS:
return appendToList(state, 'chat_mutes', me, action.accounts, action.next)
case CHAT_MESSENGER_MUTES_FETCH_FAIL:
case CHAT_MESSENGER_MUTES_EXPAND_FAIL:
return setListFailed(state, 'chat_mutes', me)
default:
return state;
}

@ -490,6 +490,17 @@ pre {
/* */
.cIconComposeEmoji { color: #F6B83C; }
.cIconComposeExpires { color: #EE2C4D; }
.cIconComposeMedia { color: #4BBC66; }
.cIconComposePoll { color: #F87E3A; }
.cIconComposeRichText { color: #227BEF; }
.cIconComposeSchedule { color: #ff0000; }
.cIconComposeSpoiler { color: #8C75C9; }
.cIconComposeSensitive { color: #35BBA7; }
/* */
.topNeg50PX { top: -50px; }
.topNeg20PX { top: -20px; }
.top0 { top: 0; }

@ -16,6 +16,7 @@
# chat_message_expiration_policy :string
#
# : todo : expires
class ChatConversationAccount < ApplicationRecord
include Paginable

@ -71,6 +71,18 @@ module AccountInteractions
has_many :muting, -> { order('mutes.id desc') }, through: :mute_relationships, source: :target_account
has_many :muted_by_relationships, class_name: 'Mute', foreign_key: :target_account_id, dependent: :destroy
has_many :muted_by, -> { order('mutes.id desc') }, through: :muted_by_relationships, source: :account
# Chat block relationships
has_many :chat_block_relationships, class_name: 'ChatBlock', foreign_key: 'account_id', dependent: :destroy
has_many :chat_blocking, -> { order('chat_blocks.id desc') }, through: :chat_block_relationships, source: :target_account
has_many :chat_blocked_by_relationships, class_name: 'ChatBlock', foreign_key: :target_account_id, dependent: :destroy
has_many :chat_blocked_by, -> { order('chat_blocks.id desc') }, through: :chat_blocked_by_relationships, source: :account
# Chat mute relationships
has_many :chat_mute_relationships, class_name: 'ChatMute', foreign_key: 'account_id', dependent: :destroy
has_many :chat_muting, -> { order('chat_mutes.id desc') }, through: :chat_mute_relationships, source: :target_account
has_many :chat_muted_by_relationships, class_name: 'ChatMute', foreign_key: :target_account_id, dependent: :destroy
has_many :chat_muted_by, -> { order('chat_mutes.id desc') }, through: :chat_muted_by_relationships, source: :account
end
def follow!(other_account, reblogs: nil, uri: nil)

@ -0,0 +1,9 @@
# frozen_string_literal: true
class BlockChatMessengerService < BaseService
def call(account, target_account)
return if account.id == target_account.id
block = account.chat_block!(target_account)
block
end
end

@ -0,0 +1,9 @@
# frozen_string_literal: true
class MuteChatMessengerService < BaseService
def call(account, target_account)
return if account.id == target_account.id
mute = account.chat_mute!(target_account)
mute
end
end

@ -0,0 +1,9 @@
# frozen_string_literal: true
class UnblockChatMessengerService < BaseService
def call(account, target_account)
return unless account.chat_blocking?(target_account)
unblock = account.chat_unblock!(target_account)
unblock
end
end

@ -0,0 +1,8 @@
# frozen_string_literal: true
class UnmuteChatMessengerService < BaseService
def call(account, target_account)
return unless account.chat_muting?(target_account)
account.chat_unmute!(target_account)
end
end

@ -222,11 +222,13 @@ Rails.application.routes.draw do
resource :explore, only: :show, controller: :explore
end
resources :chat_conversation_accounts, only: :show do
resources :blocked_accounts, only: :index
resources :muted_accounts, only: :index
resource :chat_conversation_accounts, only: :show do
resource :blocked_chat_accounts, only: :show, controller: 'chat_conversation_accounts/blocked_chat_accounts'
resource :muted_chat_accounts, only: :show, controller: 'chat_conversation_accounts/muted_chat_accounts'
member do
get :is_messenger_blocked
get :is_messenger_muted
post :block_messenger
post :unblock_messenger
post :mute_messenger