Progress with DMs
Progress with DMs
This commit is contained in:
parent
a129b3ce3b
commit
137a36b810
@ -70,12 +70,7 @@ module Admin
|
|||||||
end
|
end
|
||||||
|
|
||||||
def filter_params
|
def filter_params
|
||||||
params.permit(
|
params.permit(:shortcode)
|
||||||
:local,
|
|
||||||
:remote,
|
|
||||||
:by_domain,
|
|
||||||
:shortcode
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -26,7 +26,7 @@ class Api::V1::ChatConversationController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def mark_chat_conversation_unread
|
def mark_chat_conversation_unread
|
||||||
@chat_conversation_account.update!(is_unread: true)
|
@chat_conversation_account.update!(unread_count: 1)
|
||||||
render json: @chat_conversation_account, serializer: REST::ChatConversationAccountSerializer
|
render json: @chat_conversation_account, serializer: REST::ChatConversationAccountSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -4,22 +4,30 @@ class Api::V1::ChatConversations::ApprovedConversationsController < Api::BaseCon
|
|||||||
before_action -> { authorize_if_got_token! :read, :'read:chats' }
|
before_action -> { authorize_if_got_token! :read, :'read:chats' }
|
||||||
|
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
|
before_action :set_chat_conversation, only: :create
|
||||||
after_action :insert_pagination_headers
|
after_action :insert_pagination_headers
|
||||||
|
|
||||||
def index
|
def index
|
||||||
puts "tilly ApprovedConversationsController-0"
|
|
||||||
@chat_conversations = load_chat_conversations
|
@chat_conversations = load_chat_conversations
|
||||||
render json: @chat_conversations, each_serializer: REST::ChatConversationAccountSerializer
|
render json: @chat_conversations, each_serializer: REST::ChatConversationAccountSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
puts "tilly ApprovedConversationsController-1"
|
render json: @chat_conversation, serializer: REST::ChatConversationAccountSerializer
|
||||||
@chat_conversations = load_chat_conversations
|
end
|
||||||
render json: @chat_conversations, each_serializer: REST::ChatConversationAccountSerializer
|
|
||||||
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def set_chat_conversation
|
||||||
|
@chat_conversation = ChatConversationAccount.where(account: current_account).find(params[:id]).first
|
||||||
|
end
|
||||||
|
|
||||||
def load_chat_conversations
|
def load_chat_conversations
|
||||||
paginated_chat_conversations
|
paginated_chat_conversations
|
||||||
end
|
end
|
||||||
|
@ -15,6 +15,22 @@ class Api::V1::ChatConversations::MessagesController < Api::BaseController
|
|||||||
render json: @chats, each_serializer: REST::ChatMessageSerializer
|
render json: @chats, each_serializer: REST::ChatMessageSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def destroy_all
|
||||||
|
puts "tilly destry all chat"
|
||||||
|
# : todo :
|
||||||
|
# check if is pro
|
||||||
|
# @chat = ChatMessage.where(from_account: current_user.account).find(params[:id])
|
||||||
|
|
||||||
|
puts "tilly @chat: " + @chat.inspect
|
||||||
|
|
||||||
|
# : todo :
|
||||||
|
# make sure last_chat_message_id in chat_account_conversation gets set to last
|
||||||
|
|
||||||
|
# @chat.destroy!
|
||||||
|
|
||||||
|
# render json: @chat, serializer: REST::ChatMessageSerializer
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_chat_conversation
|
def set_chat_conversation
|
||||||
|
@ -5,25 +5,33 @@ class Api::V1::ChatMessagesController < Api::BaseController
|
|||||||
before_action -> { doorkeeper_authorize! :write, :'write:chats' }
|
before_action -> { doorkeeper_authorize! :write, :'write:chats' }
|
||||||
|
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
before_action :set_chat_conversation
|
before_action :set_chat_conversation, only: :create
|
||||||
|
before_action :set_chat_conversation_recipients, only: :create
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@chat = ChatMessage.create!(
|
@chat = ChatMessage.create!(
|
||||||
from_account: current_account,
|
from_account: current_account,
|
||||||
chat_conversation: @chat_conversation,
|
chat_conversation: @chat_conversation,
|
||||||
text: params[:text]
|
text: ActionController::Base.helpers.strip_tags(params[:text])
|
||||||
)
|
)
|
||||||
|
|
||||||
# : todo :
|
# : todo :
|
||||||
# Redis.current.publish("chat_messages:10", 'hi')
|
# check if blocked
|
||||||
Redis.current.publish("chat_messages:10", Oj.dump(event: :chat_message, payload: InlineRenderer.render(@chat, current_user.account, :chat_message)))
|
|
||||||
|
@chat_conversation_recipients.each do |account|
|
||||||
|
payload = InlineRenderer.render(@chat, account, :chat_message)
|
||||||
|
Redis.current.publish("chat_messages:#{account.id}", Oj.dump(event: :notification, payload: payload))
|
||||||
|
end
|
||||||
|
|
||||||
render json: @chat, serializer: REST::ChatMessageSerializer
|
render json: @chat, serializer: REST::ChatMessageSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@chat = ChatMessage.where(account: current_user.account).find(params[:id])
|
puts "tilly destry chat"
|
||||||
authorize @chat, :destroy?
|
|
||||||
|
@chat = ChatMessage.where(from_account: current_user.account).find(params[:id])
|
||||||
|
|
||||||
|
puts "tilly @chat: " + @chat.inspect
|
||||||
|
|
||||||
# : todo :
|
# : todo :
|
||||||
# make sure last_chat_message_id in chat_account_conversation gets set to last
|
# make sure last_chat_message_id in chat_account_conversation gets set to last
|
||||||
@ -39,6 +47,12 @@ class Api::V1::ChatMessagesController < Api::BaseController
|
|||||||
@chat_conversation = ChatConversation.find(params[:chat_conversation_id])
|
@chat_conversation = ChatConversation.find(params[:chat_conversation_id])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_chat_conversation_recipients
|
||||||
|
account_conversation = ChatConversationAccount.where(account: current_user.account, chat_conversation: @chat_conversation).first
|
||||||
|
puts "tilly account_conversation - " + account_conversation.inspect
|
||||||
|
@chat_conversation_recipients = Account.where(id: account_conversation.participant_account_ids)
|
||||||
|
end
|
||||||
|
|
||||||
def chat_params
|
def chat_params
|
||||||
params.permit(:text, :chat_conversation_id)
|
params.permit(:text, :chat_conversation_id)
|
||||||
end
|
end
|
||||||
|
@ -13,6 +13,8 @@ export const CHAT_CONVERSATIONS_APPROVED_EXPAND_REQUEST = 'CHAT_CONVERSATIONS_AP
|
|||||||
export const CHAT_CONVERSATIONS_APPROVED_EXPAND_SUCCESS = 'CHAT_CONVERSATIONS_APPROVED_EXPAND_SUCCESS'
|
export const CHAT_CONVERSATIONS_APPROVED_EXPAND_SUCCESS = 'CHAT_CONVERSATIONS_APPROVED_EXPAND_SUCCESS'
|
||||||
export const CHAT_CONVERSATIONS_APPROVED_EXPAND_FAIL = 'CHAT_CONVERSATIONS_APPROVED_EXPAND_FAIL'
|
export const CHAT_CONVERSATIONS_APPROVED_EXPAND_FAIL = 'CHAT_CONVERSATIONS_APPROVED_EXPAND_FAIL'
|
||||||
|
|
||||||
|
export const CHAT_CONVERSATION_APPROVED_UNREAD_COUNT_FETCH_SUCCESS = 'CHAT_CONVERSATIONS_APPROVED_EXPAND_FAIL'
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
export const CHAT_CONVERSATIONS_CREATE_REQUEST = 'CHAT_CONVERSATIONS_CREATE_REQUEST'
|
export const CHAT_CONVERSATIONS_CREATE_REQUEST = 'CHAT_CONVERSATIONS_CREATE_REQUEST'
|
||||||
@ -437,6 +439,20 @@ export const fetchChatConversationRequestedCount = () => (dispatch, getState) =>
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export const fetchChatConversationUnreadCount = () => (dispatch, getState) => {
|
||||||
|
if (!me) return
|
||||||
|
|
||||||
|
api(getState).get('/api/v1/chat_conversations/approved_conversations/unread_count').then(response => {
|
||||||
|
dispatch({
|
||||||
|
type: CHAT_CONVERSATION_APPROVED_UNREAD_COUNT_FETCH_SUCCESS,
|
||||||
|
count: response.data,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -19,7 +19,7 @@ export const sendChatMessage = (text = '', chatConversationId) => (dispatch, get
|
|||||||
if (!me || !chatConversationId) return
|
if (!me || !chatConversationId) return
|
||||||
if (text.length === 0) return
|
if (text.length === 0) return
|
||||||
|
|
||||||
dispatch(sendMessageRequest())
|
dispatch(sendChatMessageRequest(chatConversationId))
|
||||||
|
|
||||||
api(getState).post('/api/v1/chat_messages', {
|
api(getState).post('/api/v1/chat_messages', {
|
||||||
text,
|
text,
|
||||||
@ -30,23 +30,23 @@ export const sendChatMessage = (text = '', chatConversationId) => (dispatch, get
|
|||||||
// },
|
// },
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
dispatch(importFetchedChatMessages([response.data]))
|
dispatch(importFetchedChatMessages([response.data]))
|
||||||
dispatch(sendMessageSuccess(response.data, chatConversationId))
|
dispatch(sendChatMessageSuccess(response.data))
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
dispatch(sendMessageFail(error))
|
dispatch(sendChatMessageFail(error))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const sendMessageRequest = () => ({
|
const sendChatMessageRequest = (chatConversationId) => ({
|
||||||
type: CHAT_MESSAGES_SEND_REQUEST,
|
type: CHAT_MESSAGES_SEND_REQUEST,
|
||||||
})
|
|
||||||
|
|
||||||
const sendMessageSuccess = (chatMessage, chatConversationId) => ({
|
|
||||||
type: CHAT_MESSAGES_SEND_SUCCESS,
|
|
||||||
chatMessage,
|
|
||||||
chatConversationId,
|
chatConversationId,
|
||||||
})
|
})
|
||||||
|
|
||||||
const sendMessageFail = (error) => ({
|
export const sendChatMessageSuccess = (chatMessage) => ({
|
||||||
|
type: CHAT_MESSAGES_SEND_SUCCESS,
|
||||||
|
chatMessage,
|
||||||
|
})
|
||||||
|
|
||||||
|
const sendChatMessageFail = (error) => ({
|
||||||
type: CHAT_MESSAGES_SEND_FAIL,
|
type: CHAT_MESSAGES_SEND_FAIL,
|
||||||
error,
|
error,
|
||||||
})
|
})
|
||||||
@ -54,32 +54,32 @@ const sendMessageFail = (error) => ({
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
const deleteMessage = (chatMessageId) => (dispatch, getState) => {
|
export const deleteChatMessage = (chatMessageId) => (dispatch, getState) => {
|
||||||
if (!me || !chatMessageId) return
|
if (!me || !chatMessageId) return
|
||||||
|
|
||||||
dispatch(deleteMessageRequest(chatMessageId))
|
dispatch(deleteChatMessageRequest(chatMessageId))
|
||||||
|
|
||||||
api(getState).delete(`/api/v1/chat_messages/${chatMessageId}`, {}, {
|
api(getState).delete(`/api/v1/chat_messages/${chatMessageId}`, {}, {
|
||||||
// headers: {
|
// headers: {
|
||||||
// 'Idempotency-Key': getState().getIn(['chat_compose', 'idempotencyKey']),
|
// 'Idempotency-Key': getState().getIn(['chat_compose', 'idempotencyKey']),
|
||||||
// },
|
// },
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
deleteMessageSuccess(response)
|
dispatch(deleteChatMessageSuccess(response.data))
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
dispatch(deleteMessageFail(error))
|
dispatch(deleteChatMessageFail(error))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteMessageRequest = (chatMessageId) => ({
|
const deleteChatMessageRequest = (chatMessageId) => ({
|
||||||
type: CHAT_MESSAGES_DELETE_REQUEST,
|
type: CHAT_MESSAGES_DELETE_REQUEST,
|
||||||
chatMessageId,
|
chatMessageId,
|
||||||
})
|
})
|
||||||
|
|
||||||
const deleteMessageSuccess = () => ({
|
const deleteChatMessageSuccess = () => ({
|
||||||
type: CHAT_MESSAGES_DELETE_SUCCESS,
|
type: CHAT_MESSAGES_DELETE_SUCCESS,
|
||||||
})
|
})
|
||||||
|
|
||||||
const deleteMessageFail = (error) => ({
|
const deleteChatMessageFail = (error) => ({
|
||||||
type: CHAT_MESSAGES_DELETE_FAIL,
|
type: CHAT_MESSAGES_DELETE_FAIL,
|
||||||
error,
|
error,
|
||||||
})
|
})
|
@ -6,6 +6,7 @@ import {
|
|||||||
updateTimelineQueue,
|
updateTimelineQueue,
|
||||||
} from './timelines'
|
} from './timelines'
|
||||||
import { updateNotificationsQueue } from './notifications'
|
import { updateNotificationsQueue } from './notifications'
|
||||||
|
import { sendChatMessageSuccess } from './chat_messages'
|
||||||
import { fetchFilters } from './filters'
|
import { fetchFilters } from './filters'
|
||||||
import { getLocale } from '../locales'
|
import { getLocale } from '../locales'
|
||||||
import { handleComposeSubmit } from './compose'
|
import { handleComposeSubmit } from './compose'
|
||||||
@ -76,17 +77,15 @@ export const connectUserStream = () => connectTimelineStream('home', 'user')
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export const connectChatMessagesStream = (accountId) => {
|
export const connectChatMessagesStream = (accountId) => {
|
||||||
return connectStream(`chat_messages:${accountId}`, null, (dispatch, getState) => {
|
return connectStream(`chat_messages`, null, (dispatch, getState) => {
|
||||||
return {
|
return {
|
||||||
onConnect() {
|
onConnect() {},
|
||||||
// console.log("chat messages connected")
|
onDisconnect() {},
|
||||||
},
|
|
||||||
onDisconnect() {
|
|
||||||
// console.log("chat messages disconnected")
|
|
||||||
},
|
|
||||||
onReceive (data) {
|
onReceive (data) {
|
||||||
// : todo :
|
if (!data['event'] || !data['payload']) return
|
||||||
console.log("chat messages onReceive:", data)
|
if (data.event === 'notification') {
|
||||||
|
dispatch(sendChatMessageSuccess(JSON.parse(data.payload)))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -81,6 +81,7 @@ class ListItem extends React.PureComponent {
|
|||||||
const textContainerClasses = CX({
|
const textContainerClasses = CX({
|
||||||
d: 1,
|
d: 1,
|
||||||
pr5: 1,
|
pr5: 1,
|
||||||
|
w100PC: hideArrow,
|
||||||
maxW100PC42PX: !hideArrow || showActive,
|
maxW100PC42PX: !hideArrow || showActive,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -67,6 +67,8 @@ class DefaultNavigationBar extends ImmutablePureComponent {
|
|||||||
account,
|
account,
|
||||||
noActions,
|
noActions,
|
||||||
logoDisabled,
|
logoDisabled,
|
||||||
|
unreadChatsCount,
|
||||||
|
notificationCount,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
const navigationContainerClasses = CX({
|
const navigationContainerClasses = CX({
|
||||||
@ -171,7 +173,8 @@ class DefaultNavigationBar extends ImmutablePureComponent {
|
|||||||
|
|
||||||
<div className={[_s.d, _s.h20PX, _s.w1PX, _s.mr10, _s.ml10, _s.bgNavigationBlend].join(' ')} />
|
<div className={[_s.d, _s.h20PX, _s.w1PX, _s.mr10, _s.ml10, _s.bgNavigationBlend].join(' ')} />
|
||||||
|
|
||||||
<NavigationBarButton attrTitle='Notifications' icon='notifications' to='/notifications' />
|
<NavigationBarButton attrTitle='Notifications' icon='notifications' to='/notifications' count={notificationCount} />
|
||||||
|
<NavigationBarButton attrTitle='Chats' icon='chat' to='/messages' count={unreadChatsCount} />
|
||||||
<NavigationBarButton attrTitle='Dark/Muted/Light/White Mode' icon='light-bulb' onClick={this.handleOnClickLightBulb} />
|
<NavigationBarButton attrTitle='Dark/Muted/Light/White Mode' icon='light-bulb' onClick={this.handleOnClickLightBulb} />
|
||||||
|
|
||||||
<div className={[_s.d, _s.h20PX, _s.w1PX, _s.mr10, _s.ml10, _s.bgNavigationBlend].join(' ')} />
|
<div className={[_s.d, _s.h20PX, _s.w1PX, _s.mr10, _s.ml10, _s.bgNavigationBlend].join(' ')} />
|
||||||
@ -236,6 +239,7 @@ class DefaultNavigationBar extends ImmutablePureComponent {
|
|||||||
attrTitle={action.attrTitle}
|
attrTitle={action.attrTitle}
|
||||||
title={action.title}
|
title={action.title}
|
||||||
icon={action.icon}
|
icon={action.icon}
|
||||||
|
count={action.count}
|
||||||
to={action.to || undefined}
|
to={action.to || undefined}
|
||||||
onClick={action.onClick ? () => action.onClick() : undefined}
|
onClick={action.onClick ? () => action.onClick() : undefined}
|
||||||
key={`action-btn-${i}`}
|
key={`action-btn-${i}`}
|
||||||
@ -261,6 +265,8 @@ const mapStateToProps = (state) => ({
|
|||||||
emailConfirmationResends: state.getIn(['user', 'emailConfirmationResends'], 0),
|
emailConfirmationResends: state.getIn(['user', 'emailConfirmationResends'], 0),
|
||||||
theme: state.getIn(['settings', 'displayOptions', 'theme'], DEFAULT_THEME),
|
theme: state.getIn(['settings', 'displayOptions', 'theme'], DEFAULT_THEME),
|
||||||
logoDisabled: state.getIn(['settings', 'displayOptions', 'logoDisabled'], false),
|
logoDisabled: state.getIn(['settings', 'displayOptions', 'logoDisabled'], false),
|
||||||
|
notificationCount: state.getIn(['notifications', 'unread']),
|
||||||
|
unreadChatsCount: state.getIn(['chats', 'chatsUnreadCount']),
|
||||||
})
|
})
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
@ -288,6 +294,8 @@ DefaultNavigationBar.propTypes = {
|
|||||||
tabs: PropTypes.array,
|
tabs: PropTypes.array,
|
||||||
title: PropTypes.string,
|
title: PropTypes.string,
|
||||||
showBackBtn: PropTypes.bool,
|
showBackBtn: PropTypes.bool,
|
||||||
|
notificationCount: PropTypes.number.isRequired,
|
||||||
|
unreadChatsCount: PropTypes.number.isRequired,
|
||||||
onOpenNavSettingsPopover: PropTypes.func.isRequired,
|
onOpenNavSettingsPopover: PropTypes.func.isRequired,
|
||||||
onOpenEmailModal: PropTypes.func.isRequired,
|
onOpenEmailModal: PropTypes.func.isRequired,
|
||||||
onResendUserConfirmationEmail: PropTypes.func.isRequired,
|
onResendUserConfirmationEmail: PropTypes.func.isRequired,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
import { shortNumberFormat } from '../utils/numbers'
|
||||||
import { CX } from '../constants'
|
import { CX } from '../constants'
|
||||||
import Button from './button'
|
import Button from './button'
|
||||||
import Icon from './icon'
|
import Icon from './icon'
|
||||||
@ -53,17 +54,22 @@ class NavigationBarButton extends React.PureComponent {
|
|||||||
|
|
||||||
const countClasses = CX({
|
const countClasses = CX({
|
||||||
d: 1,
|
d: 1,
|
||||||
|
text: 1,
|
||||||
|
textAlignCenter: 1,
|
||||||
|
minW20PX: 1,
|
||||||
|
mlAuto: 1,
|
||||||
fs12PX: 1,
|
fs12PX: 1,
|
||||||
posAbs: 1,
|
px5: 1,
|
||||||
|
mr2: 1,
|
||||||
|
lineHeight15: 1,
|
||||||
|
ml5: 1,
|
||||||
|
cWhite: 1,
|
||||||
|
rightNeg5PX: 1,
|
||||||
top0: 1,
|
top0: 1,
|
||||||
mt15: 1,
|
mt5: 1,
|
||||||
right0: 1,
|
bgRed: 1,
|
||||||
mr5: 1,
|
posAbs: 1,
|
||||||
h4PX: 1,
|
circle: 1,
|
||||||
w4PX: 1,
|
|
||||||
cBrand: 1,
|
|
||||||
bgNavigationBlend: 1,
|
|
||||||
radiusSmall: 1,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const iconContainerClasses = CX({
|
const iconContainerClasses = CX({
|
||||||
@ -112,7 +118,9 @@ class NavigationBarButton extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
!title && count > 0 &&
|
!title && count > 0 &&
|
||||||
<span className={countClasses} />
|
<span className={countClasses}>
|
||||||
|
{shortNumberFormat(count)}
|
||||||
|
</span>
|
||||||
}
|
}
|
||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,113 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
import { closePopover } from '../../actions/popover'
|
||||||
|
import { openModal } from '../../actions/modal'
|
||||||
|
import { MODAL_PRO_UPGRADE } from '../../constants'
|
||||||
|
import { me } from '../../initial_state'
|
||||||
|
import { makeGetChatConversation } from '../../selectors'
|
||||||
|
import { changeSetting, saveSettings } from '../../actions/settings'
|
||||||
|
import PopoverLayout from './popover_layout'
|
||||||
|
import List from '../list'
|
||||||
|
|
||||||
|
class ChatConversationOptionsPopover extends ImmutablePureComponent {
|
||||||
|
|
||||||
|
handleOnBlock = () => {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
handleOnHide = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
handleOnMute = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
handleOnPurge = () => {
|
||||||
|
if (!this.props.isPro) {
|
||||||
|
this.props.openProUpgradeModal()
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleOnClosePopover = () => {
|
||||||
|
this.props.onClosePopover()
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
intl,
|
||||||
|
isXS,
|
||||||
|
} = this.props
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
hideArrow: true,
|
||||||
|
title: 'Block Messenger',
|
||||||
|
subtitle: 'The messenger will not be able to message you.',
|
||||||
|
onClick: () => this.handleOnBlock(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hideArrow: true,
|
||||||
|
title: 'Mute Messenger',
|
||||||
|
subtitle: 'You will not be notified of new messsages',
|
||||||
|
onClick: () => this.handleOnMute(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hideArrow: true,
|
||||||
|
title: 'Hide Conversation',
|
||||||
|
subtitle: 'Hide until next message',
|
||||||
|
onClick: () => this.handleOnHide(),
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
hideArrow: true,
|
||||||
|
title: 'Purge messages',
|
||||||
|
subtitle: 'Remove all of your messages in this conversation',
|
||||||
|
onClick: () => this.handleOnPurge(),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PopoverLayout
|
||||||
|
width={220}
|
||||||
|
isXS={isXS}
|
||||||
|
onClose={this.handleOnClosePopover}
|
||||||
|
>
|
||||||
|
<List
|
||||||
|
size={isXS ? 'large' : 'small'}
|
||||||
|
scrollKey='chat_conversation_options'
|
||||||
|
items={items}
|
||||||
|
/>
|
||||||
|
</PopoverLayout>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = (state, { chatConversationId }) => ({
|
||||||
|
isPro: state.getIn(['accounts', me, 'is_pro']),
|
||||||
|
chatConversation: makeGetChatConversation()(state, { id: chatConversationId }),
|
||||||
|
})
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
openProUpgradeModal() {
|
||||||
|
dispatch(openModal(MODAL_PRO_UPGRADE))
|
||||||
|
},
|
||||||
|
onSetCommentSortingSetting(type) {
|
||||||
|
dispatch(closePopover())
|
||||||
|
},
|
||||||
|
onClosePopover: () => dispatch(closePopover()),
|
||||||
|
})
|
||||||
|
|
||||||
|
ChatConversationOptionsPopover.propTypes = {
|
||||||
|
isXS: PropTypes.bool,
|
||||||
|
isPro: PropTypes.bool.isRequired,
|
||||||
|
chatConversation: ImmutablePropTypes.map,
|
||||||
|
onClosePopover: PropTypes.func.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(ChatConversationOptionsPopover)
|
@ -0,0 +1,54 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
import { closePopover } from '../../actions/popover'
|
||||||
|
import { deleteChatMessage } from '../../actions/chat_messages'
|
||||||
|
import PopoverLayout from './popover_layout'
|
||||||
|
import Button from '../button'
|
||||||
|
import Text from '../text'
|
||||||
|
|
||||||
|
class ChatMessageDeletePopover extends React.PureComponent {
|
||||||
|
|
||||||
|
handleOnClick = () => {
|
||||||
|
this.props.onDeleteChatMessage(this.props.chatMessageId)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleOnClosePopover = () => {
|
||||||
|
this.props.onClosePopover()
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { isXS } = this.props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PopoverLayout
|
||||||
|
width={96}
|
||||||
|
isXS={isXS}
|
||||||
|
onClose={this.handleOnClosePopover}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
onClick={this.handleOnClick}
|
||||||
|
color='primary'
|
||||||
|
backgroundColor='tertiary'
|
||||||
|
className={[_s.radiusSmall].join(' ')}
|
||||||
|
>
|
||||||
|
<Text align='center' color='inherit'>Remove</Text>
|
||||||
|
</Button>
|
||||||
|
</PopoverLayout>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
onDeleteChatMessage(chatMessageId) {
|
||||||
|
dispatch(deleteChatMessage(chatMessageId))
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
ChatMessageDeletePopover.propTypes = {
|
||||||
|
isXS: PropTypes.bool,
|
||||||
|
chatMessageId: PropTypes.string.isRequired,
|
||||||
|
onDeleteChatMessage: PropTypes.func.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(null, mapDispatchToProps)(ChatMessageDeletePopover)
|
@ -1,5 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
BREAKPOINT_EXTRA_SMALL,
|
BREAKPOINT_EXTRA_SMALL,
|
||||||
|
POPOVER_CHAT_CONVERSATION_OPTIONS,
|
||||||
|
POPOVER_CHAT_MESSAGE_DELETE,
|
||||||
POPOVER_COMMENT_SORTING_OPTIONS,
|
POPOVER_COMMENT_SORTING_OPTIONS,
|
||||||
POPOVER_DATE_PICKER,
|
POPOVER_DATE_PICKER,
|
||||||
POPOVER_EMOJI_PICKER,
|
POPOVER_EMOJI_PICKER,
|
||||||
@ -20,6 +22,8 @@ import {
|
|||||||
POPOVER_VIDEO_STATS,
|
POPOVER_VIDEO_STATS,
|
||||||
} from '../../constants'
|
} from '../../constants'
|
||||||
import {
|
import {
|
||||||
|
ChatConversationOptionsPopover,
|
||||||
|
ChatMessageDeletePopover,
|
||||||
CommentSortingOptionsPopover,
|
CommentSortingOptionsPopover,
|
||||||
DatePickerPopover,
|
DatePickerPopover,
|
||||||
EmojiPickerPopover,
|
EmojiPickerPopover,
|
||||||
@ -53,25 +57,28 @@ import LoadingPopover from './loading_popover'
|
|||||||
|
|
||||||
const initialState = getWindowDimension()
|
const initialState = getWindowDimension()
|
||||||
|
|
||||||
const POPOVER_COMPONENTS = {}
|
const POPOVER_COMPONENTS = {
|
||||||
POPOVER_COMPONENTS[POPOVER_COMMENT_SORTING_OPTIONS] = CommentSortingOptionsPopover
|
[POPOVER_CHAT_CONVERSATION_OPTIONS]: ChatConversationOptionsPopover,
|
||||||
POPOVER_COMPONENTS[POPOVER_DATE_PICKER] = DatePickerPopover
|
[POPOVER_CHAT_MESSAGE_DELETE]: ChatMessageDeletePopover,
|
||||||
POPOVER_COMPONENTS[POPOVER_EMOJI_PICKER] = EmojiPickerPopover
|
[POPOVER_COMMENT_SORTING_OPTIONS]: CommentSortingOptionsPopover,
|
||||||
POPOVER_COMPONENTS[POPOVER_GROUP_LIST_SORT_OPTIONS] = GroupListSortOptionsPopover
|
[POPOVER_DATE_PICKER]: DatePickerPopover,
|
||||||
POPOVER_COMPONENTS[POPOVER_GROUP_MEMBER_OPTIONS] = GroupMemberOptionsPopover
|
[POPOVER_EMOJI_PICKER]: EmojiPickerPopover,
|
||||||
POPOVER_COMPONENTS[POPOVER_GROUP_OPTIONS] = GroupOptionsPopover
|
[POPOVER_GROUP_LIST_SORT_OPTIONS]: GroupListSortOptionsPopover,
|
||||||
POPOVER_COMPONENTS[POPOVER_GROUP_TIMELINE_SORT_OPTIONS] = GroupTimelineSortOptionsPopover
|
[POPOVER_GROUP_MEMBER_OPTIONS]: GroupMemberOptionsPopover,
|
||||||
POPOVER_COMPONENTS[POPOVER_GROUP_TIMELINE_SORT_TOP_OPTIONS] = GroupTimelineSortTopOptionsPopover
|
[POPOVER_GROUP_OPTIONS]: GroupOptionsPopover,
|
||||||
POPOVER_COMPONENTS[POPOVER_NAV_SETTINGS] = NavSettingsPopover
|
[POPOVER_GROUP_TIMELINE_SORT_OPTIONS]: GroupTimelineSortOptionsPopover,
|
||||||
POPOVER_COMPONENTS[POPOVER_PROFILE_OPTIONS] = ProfileOptionsPopover
|
[POPOVER_GROUP_TIMELINE_SORT_TOP_OPTIONS]: GroupTimelineSortTopOptionsPopover,
|
||||||
POPOVER_COMPONENTS[POPOVER_SIDEBAR_MORE] = SidebarMorePopover
|
[POPOVER_NAV_SETTINGS]: NavSettingsPopover,
|
||||||
POPOVER_COMPONENTS[POPOVER_STATUS_OPTIONS] = StatusOptionsPopover
|
[POPOVER_PROFILE_OPTIONS]: ProfileOptionsPopover,
|
||||||
POPOVER_COMPONENTS[POPOVER_STATUS_EXPIRATION_OPTIONS] = StatusExpirationOptionsPopover
|
[POPOVER_SIDEBAR_MORE]: SidebarMorePopover,
|
||||||
POPOVER_COMPONENTS[POPOVER_STATUS_SHARE] = StatusSharePopover
|
[POPOVER_STATUS_OPTIONS]: StatusOptionsPopover,
|
||||||
POPOVER_COMPONENTS[POPOVER_STATUS_VISIBILITY] = StatusVisibilityPopover
|
[POPOVER_STATUS_EXPIRATION_OPTIONS]: StatusExpirationOptionsPopover,
|
||||||
POPOVER_COMPONENTS[POPOVER_TIMELINE_INJECTION_OPTIONS] = TimelineInjectionOptionsPopover
|
[POPOVER_STATUS_SHARE]: StatusSharePopover,
|
||||||
POPOVER_COMPONENTS[POPOVER_USER_INFO] = UserInfoPopover
|
[POPOVER_STATUS_VISIBILITY]: StatusVisibilityPopover,
|
||||||
POPOVER_COMPONENTS[POPOVER_VIDEO_STATS] = VideoStatsPopover
|
[POPOVER_TIMELINE_INJECTION_OPTIONS]: TimelineInjectionOptionsPopover,
|
||||||
|
[POPOVER_USER_INFO]: UserInfoPopover,
|
||||||
|
[POPOVER_VIDEO_STATS]: VideoStatsPopover,
|
||||||
|
}
|
||||||
|
|
||||||
class PopoverRoot extends React.PureComponent {
|
class PopoverRoot extends React.PureComponent {
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ class DefaultSidebar extends ImmutablePureComponent {
|
|||||||
title,
|
title,
|
||||||
showBackBtn,
|
showBackBtn,
|
||||||
shortcuts,
|
shortcuts,
|
||||||
|
unreadChatsCount,
|
||||||
} = this.props
|
} = this.props
|
||||||
const { hoveringShortcuts } = this.state
|
const { hoveringShortcuts } = this.state
|
||||||
|
|
||||||
@ -82,7 +83,7 @@ class DefaultSidebar extends ImmutablePureComponent {
|
|||||||
</SidebarSectionTitle>
|
</SidebarSectionTitle>
|
||||||
<SidebarSectionItem title='Home' icon='home' to='/home' count={homeItemsQueueCount} />
|
<SidebarSectionItem title='Home' icon='home' to='/home' count={homeItemsQueueCount} />
|
||||||
<SidebarSectionItem title='Notifications' icon='notifications' to='/notifications' count={notificationCount} />
|
<SidebarSectionItem title='Notifications' icon='notifications' to='/notifications' count={notificationCount} />
|
||||||
<SidebarSectionItem title='Chats' icon='chat' to='/messages' />
|
<SidebarSectionItem title='Chats' icon='chat' to='/messages' count={unreadChatsCount} />
|
||||||
<SidebarSectionItem title='Groups' icon='group' to='/groups' />
|
<SidebarSectionItem title='Groups' icon='group' to='/groups' />
|
||||||
<SidebarSectionItem title='Lists' icon='list' to='/lists' />
|
<SidebarSectionItem title='Lists' icon='list' to='/lists' />
|
||||||
<SidebarSectionItem title='Explore' icon='explore' to='/explore' />
|
<SidebarSectionItem title='Explore' icon='explore' to='/explore' />
|
||||||
@ -151,6 +152,7 @@ const mapStateToProps = (state) => ({
|
|||||||
shortcuts: state.getIn(['shortcuts', 'items']),
|
shortcuts: state.getIn(['shortcuts', 'items']),
|
||||||
moreOpen: state.getIn(['popover', 'popoverType']) === 'SIDEBAR_MORE',
|
moreOpen: state.getIn(['popover', 'popoverType']) === 'SIDEBAR_MORE',
|
||||||
notificationCount: state.getIn(['notifications', 'unread']),
|
notificationCount: state.getIn(['notifications', 'unread']),
|
||||||
|
unreadChatsCount: state.getIn(['chats', 'chatsUnreadCount']),
|
||||||
homeItemsQueueCount: state.getIn(['timelines', 'home', 'totalQueuedItemsCount']),
|
homeItemsQueueCount: state.getIn(['timelines', 'home', 'totalQueuedItemsCount']),
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -170,6 +172,7 @@ DefaultSidebar.propTypes = {
|
|||||||
openSidebarMorePopover: PropTypes.func.isRequired,
|
openSidebarMorePopover: PropTypes.func.isRequired,
|
||||||
notificationCount: PropTypes.number.isRequired,
|
notificationCount: PropTypes.number.isRequired,
|
||||||
homeItemsQueueCount: PropTypes.number.isRequired,
|
homeItemsQueueCount: PropTypes.number.isRequired,
|
||||||
|
unreadChatsCount: PropTypes.number.isRequired,
|
||||||
actions: PropTypes.array,
|
actions: PropTypes.array,
|
||||||
tabs: PropTypes.array,
|
tabs: PropTypes.array,
|
||||||
title: PropTypes.string,
|
title: PropTypes.string,
|
||||||
|
@ -45,7 +45,7 @@ class SidebarSectionItem extends React.PureComponent {
|
|||||||
const iconSize = '16px'
|
const iconSize = '16px'
|
||||||
const currentPathname = noRouter ? '' : this.context.router.route.location.pathname
|
const currentPathname = noRouter ? '' : this.context.router.route.location.pathname
|
||||||
const shouldShowActive = hovering || active || currentPathname === to || currentPathname === href
|
const shouldShowActive = hovering || active || currentPathname === to || currentPathname === href
|
||||||
const isNotifications = to === '/notifications'
|
const isHighlighted = ['/notifications', '/messages'].indexOf(to) > -1
|
||||||
|
|
||||||
const containerClasses = CX({
|
const containerClasses = CX({
|
||||||
d: 1,
|
d: 1,
|
||||||
@ -67,16 +67,18 @@ class SidebarSectionItem extends React.PureComponent {
|
|||||||
const countClasses = CX({
|
const countClasses = CX({
|
||||||
d: 1,
|
d: 1,
|
||||||
text: 1,
|
text: 1,
|
||||||
|
textAlignCenter: 1,
|
||||||
|
minW20PX: 1,
|
||||||
mlAuto: 1,
|
mlAuto: 1,
|
||||||
fs12PX: 1,
|
fs12PX: 1,
|
||||||
px5: 1,
|
px5: 1,
|
||||||
mr2: 1,
|
mr2: 1,
|
||||||
lineHeight15: 1,
|
lineHeight15: 1,
|
||||||
ml5: 1,
|
ml5: 1,
|
||||||
cSecondary: !isNotifications,
|
cSecondary: !isHighlighted,
|
||||||
cWhite: isNotifications,
|
cWhite: isHighlighted,
|
||||||
bgBrand: isNotifications,
|
bgRed: isHighlighted,
|
||||||
radiusSmall: isNotifications,
|
circle: isHighlighted,
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -22,6 +22,8 @@ export const URL_GAB_PRO = 'https://pro.gab.com'
|
|||||||
|
|
||||||
export const PLACEHOLDER_MISSING_HEADER_SRC = '/original/missing.png'
|
export const PLACEHOLDER_MISSING_HEADER_SRC = '/original/missing.png'
|
||||||
|
|
||||||
|
export const POPOVER_CHAT_CONVERSATION_OPTIONS = 'CHAT_CONVERSATION_OPTIONS'
|
||||||
|
export const POPOVER_CHAT_MESSAGE_DELETE = 'CHAT_MESSAGE_DELETE'
|
||||||
export const POPOVER_COMMENT_SORTING_OPTIONS = 'COMMENT_SORTING_OPTIONS'
|
export const POPOVER_COMMENT_SORTING_OPTIONS = 'COMMENT_SORTING_OPTIONS'
|
||||||
export const POPOVER_DATE_PICKER = 'DATE_PICKER'
|
export const POPOVER_DATE_PICKER = 'DATE_PICKER'
|
||||||
export const POPOVER_EMOJI_PICKER = 'EMOJI_PICKER'
|
export const POPOVER_EMOJI_PICKER = 'EMOJI_PICKER'
|
||||||
|
@ -11,6 +11,7 @@ import { ScrollContext } from 'react-router-scroll-4'
|
|||||||
import { IntlProvider, addLocaleData } from 'react-intl'
|
import { IntlProvider, addLocaleData } from 'react-intl'
|
||||||
import { fetchCustomEmojis } from '../actions/custom_emojis'
|
import { fetchCustomEmojis } from '../actions/custom_emojis'
|
||||||
import { fetchPromotions } from '../actions/promotions'
|
import { fetchPromotions } from '../actions/promotions'
|
||||||
|
import { fetchChatConversationUnreadCount } from '../actions/chat_conversations'
|
||||||
import { hydrateStore } from '../actions/store'
|
import { hydrateStore } from '../actions/store'
|
||||||
import { MIN_ACCOUNT_CREATED_AT_ONBOARDING } from '../constants'
|
import { MIN_ACCOUNT_CREATED_AT_ONBOARDING } from '../constants'
|
||||||
import {
|
import {
|
||||||
@ -35,6 +36,7 @@ const hydrateAction = hydrateStore(initialState)
|
|||||||
store.dispatch(hydrateAction)
|
store.dispatch(hydrateAction)
|
||||||
store.dispatch(fetchCustomEmojis())
|
store.dispatch(fetchCustomEmojis())
|
||||||
store.dispatch(fetchPromotions())
|
store.dispatch(fetchPromotions())
|
||||||
|
store.dispatch(fetchChatConversationUnreadCount())
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
accountCreatedAt: !!me ? state.getIn(['accounts', me, 'created_at']) : undefined,
|
accountCreatedAt: !!me ? state.getIn(['accounts', me, 'created_at']) : undefined,
|
||||||
|
@ -17,7 +17,6 @@ import ScrollableList from '../../../components/scrollable_list'
|
|||||||
class ChatConversationsList extends ImmutablePureComponent {
|
class ChatConversationsList extends ImmutablePureComponent {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
console.log("componentDidMount:", this.props.source)
|
|
||||||
this.props.onFetchChatConversations(this.props.source)
|
this.props.onFetchChatConversations(this.props.source)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,8 +32,6 @@ class ChatConversationsList extends ImmutablePureComponent {
|
|||||||
chatConversationIds,
|
chatConversationIds,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
console.log("---source:", source, chatConversationIds)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={[_s.d, _s.w100PC, _s.overflowHidden, _s.boxShadowNone].join(' ')}>
|
<div className={[_s.d, _s.w100PC, _s.overflowHidden, _s.boxShadowNone].join(' ')}>
|
||||||
<ScrollableList
|
<ScrollableList
|
||||||
|
@ -61,7 +61,9 @@ class ChatConversationsListItem extends ImmutablePureComponent {
|
|||||||
const avatarSize = 46
|
const avatarSize = 46
|
||||||
const otherAccounts = chatConversation.get('other_accounts')
|
const otherAccounts = chatConversation.get('other_accounts')
|
||||||
const lastMessage = chatConversation.get('last_chat_message', null)
|
const lastMessage = chatConversation.get('last_chat_message', null)
|
||||||
const content = { __html: !!lastMessage ? lastMessage.get('text', '') : '' }
|
let lastMessageText = !!lastMessage ? lastMessage.get('text', '') : ''
|
||||||
|
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 date = !!lastMessage ? lastMessage.get('created_at') : chatConversation.get('created_at')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -9,6 +9,7 @@ import { sendChatMessage } from '../../../actions/chat_messages'
|
|||||||
import { CX } from '../../../constants'
|
import { CX } from '../../../constants'
|
||||||
import Button from '../../../components/button'
|
import Button from '../../../components/button'
|
||||||
import Input from '../../../components/input'
|
import Input from '../../../components/input'
|
||||||
|
import Text from '../../../components/text'
|
||||||
|
|
||||||
class ChatMessagesComposeForm extends React.PureComponent {
|
class ChatMessagesComposeForm extends React.PureComponent {
|
||||||
|
|
||||||
@ -90,13 +91,13 @@ class ChatMessagesComposeForm extends React.PureComponent {
|
|||||||
maxH200PX: 1,
|
maxH200PX: 1,
|
||||||
borderColorSecondary: 1,
|
borderColorSecondary: 1,
|
||||||
border1PX: 1,
|
border1PX: 1,
|
||||||
radiusSmall: 1,
|
radiusRounded: 1,
|
||||||
py10: 1,
|
py10: 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={[_s.d, _s.posAbs, _s.bottom0, _s.left0, _s.right0, _s.flexRow, _s.aiCenter, _s.minH58PX, _s.bgPrimary, _s.w100PC, _s.borderTop1PX, _s.borderColorSecondary, _s.px15, _s.py5].join(' ')}>
|
<div className={[_s.d, _s.posAbs, _s.bottom0, _s.left0, _s.right0, _s.flexRow, _s.aiCenter, _s.minH58PX, _s.bgPrimary, _s.w100PC, _s.borderTop1PX, _s.borderColorSecondary, _s.px15].join(' ')}>
|
||||||
<div className={[_s.d, _s.pr15, _s.flexGrow1].join(' ')}>
|
<div className={[_s.d, _s.pr15, _s.flexGrow1, _s.py10].join(' ')}>
|
||||||
<Textarea
|
<Textarea
|
||||||
id='chat-message-compose-input'
|
id='chat-message-compose-input'
|
||||||
inputRef={this.setTextbox}
|
inputRef={this.setTextbox}
|
||||||
@ -112,12 +113,12 @@ class ChatMessagesComposeForm extends React.PureComponent {
|
|||||||
aria-autocomplete='list'
|
aria-autocomplete='list'
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className={[_s.d, _s.h100PC, _s.mtAuto, _s.pb5].join(' ')}>
|
<div className={[_s.d, _s.h100PC, _s.aiCenter, _s.jcCenter].join(' ')}>
|
||||||
<Button
|
<Button
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onClick={this.handleOnSendChatMessage}
|
onClick={this.handleOnSendChatMessage}
|
||||||
>
|
>
|
||||||
Send
|
<Text color='inherit' className={_s.px10}>Send</Text>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,9 +4,11 @@ import ImmutablePureComponent from 'react-immutable-pure-component'
|
|||||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import { makeGetChatConversation } from '../../../selectors'
|
import { makeGetChatConversation } from '../../../selectors'
|
||||||
import { openModal } from '../../../actions/modal'
|
import { openPopover } from '../../../actions/popover'
|
||||||
import { approveChatConversationRequest } from '../../../actions/chat_conversations'
|
import { approveChatConversationRequest } from '../../../actions/chat_conversations'
|
||||||
import { MODAL_CHAT_CONVERSATION_CREATE } from '../../../constants'
|
import {
|
||||||
|
POPOVER_CHAT_CONVERSATION_OPTIONS
|
||||||
|
} from '../../../constants'
|
||||||
import Button from '../../../components/button'
|
import Button from '../../../components/button'
|
||||||
import AvatarGroup from '../../../components/avatar_group'
|
import AvatarGroup from '../../../components/avatar_group'
|
||||||
import DisplayName from '../../../components/display_name'
|
import DisplayName from '../../../components/display_name'
|
||||||
@ -18,6 +20,14 @@ class ChatMessageHeader extends React.PureComponent {
|
|||||||
this.props.onApproveChatConversationRequest(this.props.chatConversationId)
|
this.props.onApproveChatConversationRequest(this.props.chatConversationId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleOnOpenChatConversationOptionsPopover = () => {
|
||||||
|
this.props.onOpenChatConversationOptionsPopover(this.props.chatConversationId, this.optionsBtnRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
setOptionsBtnRef = (c) => {
|
||||||
|
this.optionsBtnRef = c
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { chatConversation } = this.props
|
const { chatConversation } = this.props
|
||||||
|
|
||||||
@ -37,8 +47,9 @@ class ChatMessageHeader extends React.PureComponent {
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
<Button
|
<Button
|
||||||
|
buttonRef={this.setOptionsBtnRef}
|
||||||
isNarrow
|
isNarrow
|
||||||
onClick={undefined}
|
onClick={this.handleOnOpenChatConversationOptionsPopover}
|
||||||
color='primary'
|
color='primary'
|
||||||
backgroundColor='secondary'
|
backgroundColor='secondary'
|
||||||
className={[_s.mlAuto, _s.px5].join(' ')}
|
className={[_s.mlAuto, _s.px5].join(' ')}
|
||||||
@ -68,17 +79,22 @@ const mapStateToProps = (state, { chatConversationId }) => ({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
onOpenChatConversationCreateModal() {
|
|
||||||
dispatch(openModal(MODAL_CHAT_CONVERSATION_CREATE))
|
|
||||||
},
|
|
||||||
onApproveChatConversationRequest(chatConversationId) {
|
onApproveChatConversationRequest(chatConversationId) {
|
||||||
dispatch(approveChatConversationRequest(chatConversationId))
|
dispatch(approveChatConversationRequest(chatConversationId))
|
||||||
}
|
},
|
||||||
|
onOpenChatConversationOptionsPopover(chatConversationId, targetRef) {
|
||||||
|
dispatch(openPopover(POPOVER_CHAT_CONVERSATION_OPTIONS, {
|
||||||
|
chatConversationId,
|
||||||
|
targetRef,
|
||||||
|
position: 'bottom',
|
||||||
|
}))
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
ChatMessageHeader.propTypes = {
|
ChatMessageHeader.propTypes = {
|
||||||
onOpenChatConversationCreateModal: PropTypes.func.isRequired,
|
|
||||||
chatConversationId: PropTypes.string,
|
chatConversationId: PropTypes.string,
|
||||||
|
onApproveChatConversationRequest: PropTypes.func.isRequired,
|
||||||
|
onOpenChatConversationOptionsPopover: PropTypes.func.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(ChatMessageHeader)
|
export default connect(mapStateToProps, mapDispatchToProps)(ChatMessageHeader)
|
@ -5,7 +5,11 @@ import moment from 'moment-mini'
|
|||||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import { NavLink } from 'react-router-dom'
|
import { NavLink } from 'react-router-dom'
|
||||||
import { CX } from '../../../constants'
|
import { openPopover } from '../../../actions/popover'
|
||||||
|
import {
|
||||||
|
CX,
|
||||||
|
POPOVER_CHAT_MESSAGE_DELETE,
|
||||||
|
} from '../../../constants'
|
||||||
import { me } from '../../../initial_state'
|
import { me } from '../../../initial_state'
|
||||||
import Input from '../../../components/input'
|
import Input from '../../../components/input'
|
||||||
import Avatar from '../../../components/avatar'
|
import Avatar from '../../../components/avatar'
|
||||||
@ -47,7 +51,11 @@ class ChatMessageItem extends ImmutablePureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleMoreClick = () => {
|
handleMoreClick = () => {
|
||||||
//
|
this.props.onOpenChatMessageDeletePopover(this.props.chatMessageId, this.deleteBtnRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
setDeleteBtnRef = (c) => {
|
||||||
|
this.deleteBtnRef = c
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -65,6 +73,8 @@ class ChatMessageItem extends ImmutablePureComponent {
|
|||||||
if (!chatMessage) return <div />
|
if (!chatMessage) return <div />
|
||||||
|
|
||||||
const account = chatMessage.get('account')
|
const account = chatMessage.get('account')
|
||||||
|
if (!account) return <div />
|
||||||
|
|
||||||
const content = { __html: chatMessage.get('text') }
|
const content = { __html: chatMessage.get('text') }
|
||||||
const alt = account.get('id', null) === me
|
const alt = account.get('id', null) === me
|
||||||
const createdAt = chatMessage.get('created_at')
|
const createdAt = chatMessage.get('created_at')
|
||||||
@ -89,9 +99,10 @@ class ChatMessageItem extends ImmutablePureComponent {
|
|||||||
d: 1,
|
d: 1,
|
||||||
px15: 1,
|
px15: 1,
|
||||||
py5: 1,
|
py5: 1,
|
||||||
bgTertiary: !alt,
|
maxW80PC: 1,
|
||||||
bgSecondary: alt,
|
bgTertiary: alt,
|
||||||
circle: 1,
|
bgSecondary: !alt,
|
||||||
|
radiusRounded: 1,
|
||||||
ml10: 1,
|
ml10: 1,
|
||||||
mr10: 1,
|
mr10: 1,
|
||||||
})
|
})
|
||||||
@ -138,6 +149,7 @@ class ChatMessageItem extends ImmutablePureComponent {
|
|||||||
alt &&
|
alt &&
|
||||||
<div className={buttonContainerClasses}>
|
<div className={buttonContainerClasses}>
|
||||||
<Button
|
<Button
|
||||||
|
buttonRef={this.setDeleteBtnRef}
|
||||||
onClick={this.handleMoreClick}
|
onClick={this.handleMoreClick}
|
||||||
color='tertiary'
|
color='tertiary'
|
||||||
backgroundColor='none'
|
backgroundColor='none'
|
||||||
@ -165,15 +177,25 @@ const mapStateToProps = (state, { lastChatMessageId, chatMessageId }) => ({
|
|||||||
lastChatMessageSameSender: lastChatMessageId ? state.getIn(['chat_messages', `${lastChatMessageId}`, 'from_account_id'], null) === state.getIn(['chat_messages', `${chatMessageId}`, 'from_account_id'], null) : false,
|
lastChatMessageSameSender: lastChatMessageId ? state.getIn(['chat_messages', `${lastChatMessageId}`, 'from_account_id'], null) === state.getIn(['chat_messages', `${chatMessageId}`, 'from_account_id'], null) : false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
onOpenChatMessageDeletePopover(chatMessageId, targetRef) {
|
||||||
|
dispatch(openPopover(POPOVER_CHAT_MESSAGE_DELETE, {
|
||||||
|
targetRef,
|
||||||
|
chatMessageId,
|
||||||
|
position: 'top',
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
ChatMessageItem.propTypes = {
|
ChatMessageItem.propTypes = {
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
lastChatMessageId: PropTypes.string,
|
lastChatMessageId: PropTypes.string,
|
||||||
lastChatMessageDate: PropTypes.string,
|
lastChatMessageDate: PropTypes.string,
|
||||||
lastChatMessageSameSender: PropTypes.string,
|
lastChatMessageSameSender: PropTypes.bool,
|
||||||
chatMessageId: PropTypes.string.isRequired,
|
chatMessageId: PropTypes.string.isRequired,
|
||||||
chatMessage: ImmutablePropTypes.map,
|
chatMessage: ImmutablePropTypes.map,
|
||||||
isHidden: PropTypes.bool,
|
isHidden: PropTypes.bool,
|
||||||
alt: PropTypes.bool,
|
alt: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps)(ChatMessageItem)
|
export default connect(mapStateToProps, mapDispatchToProps)(ChatMessageItem)
|
@ -208,7 +208,7 @@ class SwitchingArea extends React.PureComponent {
|
|||||||
<WrappedRoute path='/messages/requests' exact page={MessagesPage} component={ChatConversationRequests} content={children} componentParams={{ isSettings: true, source: 'requested' }} />
|
<WrappedRoute path='/messages/requests' exact page={MessagesPage} component={ChatConversationRequests} content={children} componentParams={{ isSettings: true, source: 'requested' }} />
|
||||||
<WrappedRoute path='/messages/blocks' exact page={MessagesPage} component={ChatConversationBlockedAccounts} content={children} componentParams={{ isSettings: true }} />
|
<WrappedRoute path='/messages/blocks' exact page={MessagesPage} component={ChatConversationBlockedAccounts} content={children} componentParams={{ isSettings: true }} />
|
||||||
<WrappedRoute path='/messages/mutes' exact page={MessagesPage} component={ChatConversationMutedAccounts} content={children} componentParams={{ isSettings: true }} />
|
<WrappedRoute path='/messages/mutes' exact page={MessagesPage} component={ChatConversationMutedAccounts} content={children} componentParams={{ isSettings: true }} />
|
||||||
<WrappedRoute path='/messages/:conversationId' exact page={MessagesPage} component={Messages} content={children} componentParams={{ source: 'approved' }} />
|
<WrappedRoute path='/messages/:chatConversationId' exact page={MessagesPage} component={Messages} content={children} componentParams={{ source: 'approved' }} />
|
||||||
|
|
||||||
<WrappedRoute path='/timeline/all' exact page={CommunityPage} component={CommunityTimeline} content={children} componentParams={{ title: 'Community Feed' }} />
|
<WrappedRoute path='/timeline/all' exact page={CommunityPage} component={CommunityTimeline} content={children} componentParams={{ title: 'Community Feed' }} />
|
||||||
<WrappedRoute path='/timeline/pro' exact page={ProPage} component={ProTimeline} content={children} componentParams={{ title: 'Pro Feed' }} />
|
<WrappedRoute path='/timeline/pro' exact page={ProPage} component={ProTimeline} content={children} componentParams={{ title: 'Pro Feed' }} />
|
||||||
|
@ -12,7 +12,9 @@ export function ChatConversationCreate() { return import(/* webpackChunkName: "f
|
|||||||
export function ChatConversationCreateModal() { return import(/* webpackChunkName: "components/chat_conversation_create_modal" */'../../../components/modal/chat_conversation_create_modal') }
|
export function ChatConversationCreateModal() { return import(/* webpackChunkName: "components/chat_conversation_create_modal" */'../../../components/modal/chat_conversation_create_modal') }
|
||||||
export function ChatConversationDeleteModal() { return import(/* webpackChunkName: "components/chat_conversation_delete_modal" */'../../../components/modal/chat_conversation_delete_modal') }
|
export function ChatConversationDeleteModal() { return import(/* webpackChunkName: "components/chat_conversation_delete_modal" */'../../../components/modal/chat_conversation_delete_modal') }
|
||||||
export function ChatConversationMutedAccounts() { return import(/* webpackChunkName: "features/chat_conversation_muted_accounts" */'../../chat_conversation_muted_accounts') }
|
export function ChatConversationMutedAccounts() { return import(/* webpackChunkName: "features/chat_conversation_muted_accounts" */'../../chat_conversation_muted_accounts') }
|
||||||
|
export function ChatConversationOptionsPopover() { return import(/* webpackChunkName: "components/chat_conversation_options_popover" */'../../../components/popover/chat_conversation_options_popover') }
|
||||||
export function ChatConversationRequests() { return import(/* webpackChunkName: "features/chat_conversation_requests" */'../../chat_conversation_requests') }
|
export function ChatConversationRequests() { return import(/* webpackChunkName: "features/chat_conversation_requests" */'../../chat_conversation_requests') }
|
||||||
|
export function ChatMessageDeletePopover() { return import(/* webpackChunkName: "components/chat_message_delete_popover" */'../../../components/popover/chat_message_delete_popover') }
|
||||||
export function CommentSortingOptionsPopover() { return import(/* webpackChunkName: "components/comment_sorting_options_popover" */'../../../components/popover/comment_sorting_options_popover') }
|
export function CommentSortingOptionsPopover() { return import(/* webpackChunkName: "components/comment_sorting_options_popover" */'../../../components/popover/comment_sorting_options_popover') }
|
||||||
export function CommunityTimeline() { return import(/* webpackChunkName: "features/community_timeline" */'../../community_timeline') }
|
export function CommunityTimeline() { return import(/* webpackChunkName: "features/community_timeline" */'../../community_timeline') }
|
||||||
export function CommunityTimelineSettingsModal() { return import(/* webpackChunkName: "components/community_timeline_settings_modal" */'../../../components/modal/community_timeline_settings_modal') }
|
export function CommunityTimelineSettingsModal() { return import(/* webpackChunkName: "components/community_timeline_settings_modal" */'../../../components/modal/community_timeline_settings_modal') }
|
||||||
|
@ -41,8 +41,6 @@ class MessagesLayout extends React.PureComponent {
|
|||||||
jcEnd: 1,
|
jcEnd: 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log("currentConversationIsRequest:",currentConversationIsRequest)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout
|
<Layout
|
||||||
showBackBtn
|
showBackBtn
|
||||||
|
@ -70,6 +70,7 @@ class HomePage extends React.PureComponent {
|
|||||||
intl,
|
intl,
|
||||||
isPro,
|
isPro,
|
||||||
totalQueuedItemsCount,
|
totalQueuedItemsCount,
|
||||||
|
unreadChatsCount,
|
||||||
} = this.props
|
} = this.props
|
||||||
const { lazyLoaded } = this.state
|
const { lazyLoaded } = this.state
|
||||||
|
|
||||||
@ -80,6 +81,11 @@ class HomePage extends React.PureComponent {
|
|||||||
page='home'
|
page='home'
|
||||||
title={title}
|
title={title}
|
||||||
actions={[
|
actions={[
|
||||||
|
{
|
||||||
|
icon: 'chat',
|
||||||
|
to: '/messages',
|
||||||
|
count: unreadChatsCount,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
icon: 'search',
|
icon: 'search',
|
||||||
to: '/search',
|
to: '/search',
|
||||||
@ -117,6 +123,7 @@ const messages = defineMessages({
|
|||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
totalQueuedItemsCount: state.getIn(['timelines', 'home', 'totalQueuedItemsCount']),
|
totalQueuedItemsCount: state.getIn(['timelines', 'home', 'totalQueuedItemsCount']),
|
||||||
|
unreadChatsCount: state.getIn(['chats', 'chatsUnreadCount']),
|
||||||
isPro: state.getIn(['accounts', me, 'is_pro']),
|
isPro: state.getIn(['accounts', me, 'is_pro']),
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -125,6 +132,7 @@ HomePage.propTypes = {
|
|||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
isPro: PropTypes.bool,
|
isPro: PropTypes.bool,
|
||||||
|
unreadChatsCount: PropTypes.number.isRequired,
|
||||||
totalQueuedItemsCount: PropTypes.number.isRequired,
|
totalQueuedItemsCount: PropTypes.number.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,23 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
import isObject from 'lodash.isobject'
|
||||||
|
import { setChatConversationSelected } from '../actions/chats'
|
||||||
import PageTitle from '../features/ui/util/page_title'
|
import PageTitle from '../features/ui/util/page_title'
|
||||||
import MessagesLayout from '../layouts/messages_layout'
|
import MessagesLayout from '../layouts/messages_layout'
|
||||||
|
|
||||||
class MessagesPage extends React.PureComponent {
|
class MessagesPage extends React.PureComponent {
|
||||||
|
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
if (isObject(this.props.params)) {
|
||||||
|
const { chatConversationId } = this.props.params
|
||||||
|
if (chatConversationId) {
|
||||||
|
this.props.dispatch(setChatConversationSelected(chatConversationId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
children,
|
children,
|
||||||
@ -34,4 +47,4 @@ MessagesPage.propTypes = {
|
|||||||
source: PropTypes.string,
|
source: PropTypes.string,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MessagesPage
|
export default connect()(MessagesPage)
|
@ -97,8 +97,10 @@ export default function chat_conversation_messages(state = initialState, action)
|
|||||||
case CHAT_CONVERSATION_MESSAGES_EXPAND_SUCCESS:
|
case CHAT_CONVERSATION_MESSAGES_EXPAND_SUCCESS:
|
||||||
return expandNormalizedChatConversation(state, action.chatConversationId, fromJS(action.chatMessages), action.next, action.partial, action.isLoadingRecent)
|
return expandNormalizedChatConversation(state, action.chatConversationId, fromJS(action.chatMessages), action.next, action.partial, action.isLoadingRecent)
|
||||||
case CHAT_MESSAGES_SEND_SUCCESS:
|
case CHAT_MESSAGES_SEND_SUCCESS:
|
||||||
return updateChatMessageConversation(state, action.chatConversationId, fromJS(action.chatMessage))
|
return updateChatMessageConversation(state, action.chatMessage.chat_conversation_id, fromJS(action.chatMessage))
|
||||||
// CHAT_MESSAGES_DELETE_REQUEST
|
case CHAT_MESSAGES_DELETE_REQUEST:
|
||||||
|
// : todo :
|
||||||
|
return state
|
||||||
default:
|
default:
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,10 @@ import {
|
|||||||
fromJS,
|
fromJS,
|
||||||
} from 'immutable'
|
} from 'immutable'
|
||||||
import { me } from '../initial_state'
|
import { me } from '../initial_state'
|
||||||
|
import {
|
||||||
|
CHAT_MESSAGES_SEND_SUCCESS,
|
||||||
|
CHAT_MESSAGES_DELETE_REQUEST,
|
||||||
|
} from '../actions/chat_messages'
|
||||||
import {
|
import {
|
||||||
CHAT_CONVERSATIONS_APPROVED_FETCH_SUCCESS,
|
CHAT_CONVERSATIONS_APPROVED_FETCH_SUCCESS,
|
||||||
CHAT_CONVERSATIONS_APPROVED_EXPAND_SUCCESS,
|
CHAT_CONVERSATIONS_APPROVED_EXPAND_SUCCESS,
|
||||||
@ -22,6 +26,10 @@ export const normalizeChatConversation = (chatConversation) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setLastChatMessage = (state, chatMessage) => {
|
||||||
|
return state.setIn([chatMessage.chat_conversation_id, 'last_chat_message'], fromJS(chatMessage))
|
||||||
|
}
|
||||||
|
|
||||||
const importChatConversation = (state, chatConversation) => state.set(chatConversation.chat_conversation_id, normalizeChatConversation(chatConversation))
|
const importChatConversation = (state, chatConversation) => state.set(chatConversation.chat_conversation_id, normalizeChatConversation(chatConversation))
|
||||||
|
|
||||||
const importChatConversations = (state, chatConversations) => {
|
const importChatConversations = (state, chatConversations) => {
|
||||||
@ -37,6 +45,11 @@ export default function chat_conversations(state = initialState, action) {
|
|||||||
case CHAT_CONVERSATIONS_REQUESTED_FETCH_SUCCESS:
|
case CHAT_CONVERSATIONS_REQUESTED_FETCH_SUCCESS:
|
||||||
case CHAT_CONVERSATIONS_REQUESTED_EXPAND_SUCCESS:
|
case CHAT_CONVERSATIONS_REQUESTED_EXPAND_SUCCESS:
|
||||||
return importChatConversations(state, action.chatConversations)
|
return importChatConversations(state, action.chatConversations)
|
||||||
|
case CHAT_MESSAGES_SEND_SUCCESS:
|
||||||
|
return setLastChatMessage(state, action.chatMessage)
|
||||||
|
case CHAT_MESSAGES_DELETE_REQUEST:
|
||||||
|
// : todo : set last conversation message to one prior to this one
|
||||||
|
return state
|
||||||
default:
|
default:
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,10 @@ import {
|
|||||||
SET_CHAT_CONVERSATION_SELECTED,
|
SET_CHAT_CONVERSATION_SELECTED,
|
||||||
} from '../actions/chats'
|
} from '../actions/chats'
|
||||||
import {
|
import {
|
||||||
|
CHAT_CONVERSATION_APPROVED_UNREAD_COUNT_FETCH_SUCCESS,
|
||||||
CHAT_CONVERSATION_REQUESTED_COUNT_FETCH_SUCCESS,
|
CHAT_CONVERSATION_REQUESTED_COUNT_FETCH_SUCCESS,
|
||||||
} from '../actions/chat_conversations'
|
} from '../actions/chat_conversations'
|
||||||
import {
|
import {
|
||||||
CHAT_MESSAGES_SEND_SUCCESS,
|
|
||||||
CHAT_MESSAGES_DELETE_REQUEST,
|
|
||||||
CHAT_MESSAGES_FETCH_SUCCESS,
|
CHAT_MESSAGES_FETCH_SUCCESS,
|
||||||
CHAT_CONVERSATION_MESSAGES_EXPAND_SUCCESS,
|
CHAT_CONVERSATION_MESSAGES_EXPAND_SUCCESS,
|
||||||
} from '../actions/chat_messages'
|
} from '../actions/chat_messages'
|
||||||
@ -22,6 +21,7 @@ const initialState = ImmutableMap({
|
|||||||
createChatConversationSuggestionIds: ImmutableList(),
|
createChatConversationSuggestionIds: ImmutableList(),
|
||||||
selectedChatConversationId: null,
|
selectedChatConversationId: null,
|
||||||
chatConversationRequestCount: 0,
|
chatConversationRequestCount: 0,
|
||||||
|
chatsUnreadCount: 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
export default function chats(state = initialState, action) {
|
export default function chats(state = initialState, action) {
|
||||||
@ -32,6 +32,8 @@ export default function chats(state = initialState, action) {
|
|||||||
return state.set('selectedChatConversationId', action.chatConversationId)
|
return state.set('selectedChatConversationId', action.chatConversationId)
|
||||||
case CHAT_CONVERSATION_REQUESTED_COUNT_FETCH_SUCCESS:
|
case CHAT_CONVERSATION_REQUESTED_COUNT_FETCH_SUCCESS:
|
||||||
return state.set('chatConversationRequestCount', action.count)
|
return state.set('chatConversationRequestCount', action.count)
|
||||||
|
case CHAT_CONVERSATION_APPROVED_UNREAD_COUNT_FETCH_SUCCESS:
|
||||||
|
return state.set('chatsUnreadCount', action.count)
|
||||||
default:
|
default:
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,6 @@ export function connectStream(path, pollingRefresh = null, callbacks = () => ({
|
|||||||
},
|
},
|
||||||
|
|
||||||
received(data) {
|
received(data) {
|
||||||
console.log("received:", data)
|
|
||||||
onReceive(data);
|
onReceive(data);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
--color_red-dark: #c72c5b;
|
--color_red-dark: #c72c5b;
|
||||||
|
|
||||||
--radius-small: 8px;
|
--radius-small: 8px;
|
||||||
|
--radius-rounded: 20px;
|
||||||
--radius-circle: 9999px;
|
--radius-circle: 9999px;
|
||||||
|
|
||||||
--fs_xs: 0.8571428571rem;
|
--fs_xs: 0.8571428571rem;
|
||||||
@ -73,9 +74,9 @@
|
|||||||
|
|
||||||
:root[no-radius] {
|
:root[no-radius] {
|
||||||
--radius-small: 0 !important;
|
--radius-small: 0 !important;
|
||||||
|
--radius-rounded: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
:root[theme='white'] {
|
:root[theme='white'] {
|
||||||
--navigation_background: var(--color_white);
|
--navigation_background: var(--color_white);
|
||||||
--navigation_blend: #aaa;
|
--navigation_blend: #aaa;
|
||||||
@ -357,6 +358,7 @@ pre {
|
|||||||
|
|
||||||
.circle { border-radius: var(--radius-circle); }
|
.circle { border-radius: var(--radius-circle); }
|
||||||
.radiusSmall { border-radius: var(--radius-small); }
|
.radiusSmall { border-radius: var(--radius-small); }
|
||||||
|
.radiusRounded { border-radius: var(--radius-rounded); }
|
||||||
.topLeftRadiusSmall { border-top-left-radius: var(--radius-small); }
|
.topLeftRadiusSmall { border-top-left-radius: var(--radius-small); }
|
||||||
.topRightRadiusSmall { border-top-right-radius: var(--radius-small); }
|
.topRightRadiusSmall { border-top-right-radius: var(--radius-small); }
|
||||||
.bottomRightRadiusSmall { border-bottom-right-radius: var(--radius-small); }
|
.bottomRightRadiusSmall { border-bottom-right-radius: var(--radius-small); }
|
||||||
@ -502,6 +504,7 @@ pre {
|
|||||||
.left50PC { left: 50%; }
|
.left50PC { left: 50%; }
|
||||||
|
|
||||||
.right0 { right: 0px; }
|
.right0 { right: 0px; }
|
||||||
|
.rightNeg5PX { right: -5px; }
|
||||||
.rightAuto { right: auto; }
|
.rightAuto { right: auto; }
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
|
@ -15,6 +15,8 @@ class InlineRenderer
|
|||||||
serializer = REST::NotificationSerializer
|
serializer = REST::NotificationSerializer
|
||||||
when :conversation
|
when :conversation
|
||||||
serializer = REST::ConversationSerializer
|
serializer = REST::ConversationSerializer
|
||||||
|
when :chat_message
|
||||||
|
serializer = REST::ChatMessageSerializer
|
||||||
else
|
else
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
class AccountConversation < ApplicationRecord
|
class AccountConversation < ApplicationRecord
|
||||||
after_commit :push_to_streaming_api
|
|
||||||
|
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
belongs_to :conversation
|
belongs_to :conversation
|
||||||
belongs_to :last_status, class_name: 'Status'
|
belongs_to :last_status, class_name: 'Status'
|
||||||
@ -102,11 +100,6 @@ class AccountConversation < ApplicationRecord
|
|||||||
self.last_status_id = status_ids.last
|
self.last_status_id = status_ids.last
|
||||||
end
|
end
|
||||||
|
|
||||||
def push_to_streaming_api
|
|
||||||
return if destroyed? || !subscribed_to_timeline?
|
|
||||||
PushConversationWorker.perform_async(id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def subscribed_to_timeline?
|
def subscribed_to_timeline?
|
||||||
Redis.current.exists("subscribed:#{streaming_channel}")
|
Redis.current.exists("subscribed:#{streaming_channel}")
|
||||||
end
|
end
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
# Table name: chat_blocks
|
# Table name: chat_blocks
|
||||||
#
|
#
|
||||||
# id :bigint(8) not null, primary key
|
# id :bigint(8) not null, primary key
|
||||||
|
# account_id :integer not null
|
||||||
|
# target_account_id :integer not null
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
# account_id :bigint(8) not null
|
|
||||||
# target_account_id :bigint(8) not null
|
|
||||||
#
|
#
|
||||||
|
|
||||||
class ChatBlock < ApplicationRecord
|
class ChatBlock < ApplicationRecord
|
||||||
|
@ -3,16 +3,17 @@
|
|||||||
#
|
#
|
||||||
# Table name: chat_conversation_accounts
|
# Table name: chat_conversation_accounts
|
||||||
#
|
#
|
||||||
# id :bigint(8) not null, primary key
|
# id :bigint(8) not null, primary key
|
||||||
# account_id :bigint(8)
|
# account_id :bigint(8)
|
||||||
# chat_conversation_id :bigint(8)
|
# chat_conversation_id :bigint(8)
|
||||||
# participant_account_ids :bigint(8) default([]), not null, is an Array
|
# participant_account_ids :bigint(8) default([]), not null, is an Array
|
||||||
# last_chat_message_id :bigint(8)
|
# last_chat_message_id :bigint(8)
|
||||||
# is_unread :boolean default(FALSE), not null
|
# is_hidden :boolean default(FALSE), not null
|
||||||
# is_hidden :boolean default(FALSE), not null
|
# is_approved :boolean default(FALSE), not null
|
||||||
# is_approved :boolean default(FALSE), not null
|
# created_at :datetime not null
|
||||||
# created_at :datetime not null
|
# updated_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# unread_count :bigint(8) default(0), not null
|
||||||
|
# chat_message_expiration_policy :string
|
||||||
#
|
#
|
||||||
|
|
||||||
class ChatConversationAccount < ApplicationRecord
|
class ChatConversationAccount < ApplicationRecord
|
||||||
@ -28,7 +29,6 @@ class ChatConversationAccount < ApplicationRecord
|
|||||||
if participant_account_ids.empty?
|
if participant_account_ids.empty?
|
||||||
[account]
|
[account]
|
||||||
else
|
else
|
||||||
# : todo : dont include current_account
|
|
||||||
participants = Account.where(id: participant_account_ids)
|
participants = Account.where(id: participant_account_ids)
|
||||||
participants.empty? ? [account] : participants
|
participants.empty? ? [account] : participants
|
||||||
end
|
end
|
||||||
|
@ -3,13 +3,14 @@
|
|||||||
#
|
#
|
||||||
# Table name: chat_messages
|
# Table name: chat_messages
|
||||||
#
|
#
|
||||||
# id :bigint(8) not null, primary key
|
# id :bigint(8) not null, primary key
|
||||||
# account_id :bigint(8) not null
|
# text :text default(""), not null
|
||||||
# chat_conversation_id :bigint(8) not null
|
# language :text default(""), not null
|
||||||
# text :text default(""), not null
|
# from_account_id :integer not null
|
||||||
# language :string
|
# chat_conversation_id :integer not null
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
|
# expires_at :datetime
|
||||||
#
|
#
|
||||||
|
|
||||||
class ChatMessage < ApplicationRecord
|
class ChatMessage < ApplicationRecord
|
||||||
|
@ -3,11 +3,11 @@
|
|||||||
#
|
#
|
||||||
# Table name: chat_mutes
|
# Table name: chat_mutes
|
||||||
#
|
#
|
||||||
# id :bigint(8) not null, primary key
|
# id :bigint(8) not null, primary key
|
||||||
# created_at :datetime not null
|
# account_id :integer not null
|
||||||
# updated_at :datetime not null
|
# target_account_id :integer not null
|
||||||
# account_id :bigint(8) not null
|
# created_at :datetime not null
|
||||||
# target_account_id :bigint(8) not null
|
# updated_at :datetime not null
|
||||||
#
|
#
|
||||||
|
|
||||||
class ChatMute < ApplicationRecord
|
class ChatMute < ApplicationRecord
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class REST::ChatConversationAccountSerializer < ActiveModel::Serializer
|
class REST::ChatConversationAccountSerializer < ActiveModel::Serializer
|
||||||
attributes :id, :is_hidden, :is_approved, :is_unread, :chat_conversation_id, :created_at
|
attributes :id, :is_hidden, :is_approved, :unread_count, :is_unread, :chat_conversation_id, :created_at
|
||||||
|
|
||||||
has_many :participant_accounts, key: :other_accounts, serializer: REST::AccountSerializer
|
has_many :participant_accounts, key: :other_accounts, serializer: REST::AccountSerializer
|
||||||
has_one :last_chat_message, serializer: REST::ChatMessageSerializer, unless: :last_chat_message_id?
|
has_one :last_chat_message, serializer: REST::ChatMessageSerializer, unless: :last_chat_message_id?
|
||||||
@ -18,4 +18,8 @@ class REST::ChatConversationAccountSerializer < ActiveModel::Serializer
|
|||||||
object.last_chat_message_id.nil?
|
object.last_chat_message_id.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def is_unread
|
||||||
|
object.unread_count > 0
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -7,4 +7,13 @@ class REST::ChatMessageSerializer < ActiveModel::Serializer
|
|||||||
def id
|
def id
|
||||||
object.id.to_s
|
object.id.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def from_account_id
|
||||||
|
object.from_account_id.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def chat_conversation_id
|
||||||
|
object.chat_conversation_id.to_s
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -2,11 +2,6 @@
|
|||||||
= t('admin.accounts.title')
|
= t('admin.accounts.title')
|
||||||
|
|
||||||
.filters
|
.filters
|
||||||
.filter-subset
|
|
||||||
%strong= t('admin.accounts.location.title')
|
|
||||||
%ul
|
|
||||||
%li= filter_link_to t('admin.accounts.location.local'), remote: nil
|
|
||||||
%li= filter_link_to t('admin.accounts.location.remote'), remote: '1'
|
|
||||||
.filter-subset
|
.filter-subset
|
||||||
%strong= t('admin.accounts.moderation.title')
|
%strong= t('admin.accounts.moderation.title')
|
||||||
%ul
|
%ul
|
||||||
|
@ -1,29 +1,13 @@
|
|||||||
- content_for :page_title do
|
- content_for :page_title do
|
||||||
= t('admin.custom_emojis.title')
|
= t('admin.custom_emojis.title')
|
||||||
|
|
||||||
.filters
|
|
||||||
.filter-subset
|
|
||||||
%strong= t('admin.accounts.location.title')
|
|
||||||
%ul
|
|
||||||
%li= filter_link_to t('admin.accounts.location.all'), local: nil, remote: nil
|
|
||||||
%li
|
|
||||||
- if selected? local: '1', remote: nil
|
|
||||||
= filter_link_to t('admin.accounts.location.local'), {local: nil, remote: nil}, {local: '1', remote: nil}
|
|
||||||
- else
|
|
||||||
= filter_link_to t('admin.accounts.location.local'), local: '1', remote: nil
|
|
||||||
%li
|
|
||||||
- if selected? remote: '1', local: nil
|
|
||||||
= filter_link_to t('admin.accounts.location.remote'), {remote: nil, local: nil}, {remote: '1', local: nil}
|
|
||||||
- else
|
|
||||||
= filter_link_to t('admin.accounts.location.remote'), remote: '1', local: nil
|
|
||||||
|
|
||||||
= form_tag admin_custom_emojis_url, method: 'GET', class: 'simple_form' do
|
= form_tag admin_custom_emojis_url, method: 'GET', class: 'simple_form' do
|
||||||
.fields-group
|
.fields-group
|
||||||
- Admin::FilterHelper::CUSTOM_EMOJI_FILTERS.each do |key|
|
- Admin::FilterHelper::CUSTOM_EMOJI_FILTERS.each do |key|
|
||||||
- if params[key].present?
|
- if params[key].present?
|
||||||
= hidden_field_tag key, params[key]
|
= hidden_field_tag key, params[key]
|
||||||
|
|
||||||
- %i(shortcode by_domain).each do |key|
|
- %i(shortcode).each do |key|
|
||||||
.input.string.optional
|
.input.string.optional
|
||||||
= text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.custom_emojis.#{key}")
|
= text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.custom_emojis.#{key}")
|
||||||
|
|
||||||
|
@ -234,8 +234,16 @@ Rails.application.routes.draw do
|
|||||||
end
|
end
|
||||||
|
|
||||||
namespace :chat_conversations do
|
namespace :chat_conversations do
|
||||||
resources :messages, only: :show
|
resources :messages, only: :show do
|
||||||
resources :approved_conversations
|
member do
|
||||||
|
delete :destroy_all
|
||||||
|
end
|
||||||
|
end
|
||||||
|
resources :approved_conversations, only: :index do
|
||||||
|
collection do
|
||||||
|
get :unread_count
|
||||||
|
end
|
||||||
|
end
|
||||||
resources :requested_conversations, only: :index do
|
resources :requested_conversations, only: :index do
|
||||||
collection do
|
collection do
|
||||||
get :count
|
get :count
|
||||||
|
@ -18,9 +18,6 @@
|
|||||||
scheduled_statuses_scheduler:
|
scheduled_statuses_scheduler:
|
||||||
every: '1m'
|
every: '1m'
|
||||||
class: Scheduler::ScheduledStatusesScheduler
|
class: Scheduler::ScheduledStatusesScheduler
|
||||||
subscriptions_scheduler:
|
|
||||||
cron: '<%= Random.rand(0..59) %> <%= Random.rand(4..6) %> * * *'
|
|
||||||
class: Scheduler::SubscriptionsScheduler
|
|
||||||
media_cleanup_scheduler:
|
media_cleanup_scheduler:
|
||||||
cron: '<%= Random.rand(0..59) %> <%= Random.rand(3..5) %> * * *'
|
cron: '<%= Random.rand(0..59) %> <%= Random.rand(3..5) %> * * *'
|
||||||
class: Scheduler::MediaCleanupScheduler
|
class: Scheduler::MediaCleanupScheduler
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
class AddUnreadCountToChatConversationAccounts < ActiveRecord::Migration[5.2]
|
||||||
|
def up
|
||||||
|
add_column :chat_conversation_accounts, :unread_count, :bigint
|
||||||
|
change_column_default :chat_conversation_accounts, :unread_count, 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_column :chat_conversation_accounts, :unread_count
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,5 @@
|
|||||||
|
class RemoveIsUnreadFromChatConversationAccounts < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
safety_assured { remove_column :chat_conversation_accounts, :is_unread }
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,5 @@
|
|||||||
|
class AddExpiresAtToChatMessages < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :chat_messages, :expires_at, :datetime, null: true, default: nil
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,10 @@
|
|||||||
|
class BackfillAddUnreadCountToChatConversationAccounts < ActiveRecord::Migration[5.2]
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
def change
|
||||||
|
ChatConversationAccount.in_batches do |relation|
|
||||||
|
relation.update_all unread_count: 0
|
||||||
|
sleep(0.1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,5 @@
|
|||||||
|
class AddUnreadCountToChatConversationAccountsNotNull < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
change_column_null :chat_conversation_accounts, :unread_count, false
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,5 @@
|
|||||||
|
class AddChatMessageExpirationPolicyToChatConversationAccounts < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :chat_conversation_accounts, :chat_message_expiration_policy, :string, null: true, default: nil
|
||||||
|
end
|
||||||
|
end
|
@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2020_11_30_172733) do
|
ActiveRecord::Schema.define(version: 2020_12_03_214600) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "pg_stat_statements"
|
enable_extension "pg_stat_statements"
|
||||||
@ -207,11 +207,12 @@ ActiveRecord::Schema.define(version: 2020_11_30_172733) do
|
|||||||
t.bigint "chat_conversation_id"
|
t.bigint "chat_conversation_id"
|
||||||
t.bigint "participant_account_ids", default: [], null: false, array: true
|
t.bigint "participant_account_ids", default: [], null: false, array: true
|
||||||
t.bigint "last_chat_message_id"
|
t.bigint "last_chat_message_id"
|
||||||
t.boolean "is_unread", default: false, null: false
|
|
||||||
t.boolean "is_hidden", default: false, null: false
|
t.boolean "is_hidden", default: false, null: false
|
||||||
t.boolean "is_approved", default: false, null: false
|
t.boolean "is_approved", default: false, null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
|
t.bigint "unread_count", default: 0, null: false
|
||||||
|
t.string "chat_message_expiration_policy"
|
||||||
t.index ["account_id"], name: "index_chat_conversation_accounts_on_account_id"
|
t.index ["account_id"], name: "index_chat_conversation_accounts_on_account_id"
|
||||||
t.index ["chat_conversation_id"], name: "index_chat_conversation_accounts_on_chat_conversation_id"
|
t.index ["chat_conversation_id"], name: "index_chat_conversation_accounts_on_chat_conversation_id"
|
||||||
end
|
end
|
||||||
@ -228,6 +229,7 @@ ActiveRecord::Schema.define(version: 2020_11_30_172733) do
|
|||||||
t.integer "chat_conversation_id", null: false
|
t.integer "chat_conversation_id", null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
|
t.datetime "expires_at"
|
||||||
t.index ["from_account_id", "chat_conversation_id"], name: "index_chat_messages_on_from_account_id_and_chat_conversation_id"
|
t.index ["from_account_id", "chat_conversation_id"], name: "index_chat_messages_on_from_account_id_and_chat_conversation_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -537,8 +537,7 @@ const startWorker = (workerId) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.get('/api/v1/streaming/chat_messages', (req, res) => {
|
app.get('/api/v1/streaming/chat_messages', (req, res) => {
|
||||||
console.log("tilly hello from inside here:", req)
|
const channel = `chat_messages:1`;
|
||||||
const channel = `chat_messages:${req.chatConversationId}`;
|
|
||||||
streamFrom(channel, req, streamToHttp(req, res), streamHttpEnd(req, subscriptionHeartbeat(channel)));
|
streamFrom(channel, req, streamToHttp(req, res), streamHttpEnd(req, subscriptionHeartbeat(channel)));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -551,8 +550,6 @@ const startWorker = (workerId) => {
|
|||||||
|
|
||||||
let channel;
|
let channel;
|
||||||
|
|
||||||
console.log("tilly location.query.stream:", location.query.stream)
|
|
||||||
|
|
||||||
switch (location.query.stream) {
|
switch (location.query.stream) {
|
||||||
case 'statuscard':
|
case 'statuscard':
|
||||||
channel = `statuscard:${req.accountId}`;
|
channel = `statuscard:${req.accountId}`;
|
||||||
@ -566,8 +563,7 @@ const startWorker = (workerId) => {
|
|||||||
streamFrom(`timeline:${req.accountId}`, req, streamToWs(req, ws), streamWsEnd(req, ws), false, true);
|
streamFrom(`timeline:${req.accountId}`, req, streamToWs(req, ws), streamWsEnd(req, ws), false, true);
|
||||||
break;
|
break;
|
||||||
case 'chat_messages':
|
case 'chat_messages':
|
||||||
console.log("tilly incoming chat_messages:", req.chatConversationId, location.query.stream)
|
streamFrom(`chat_messages:${req.accountId}`, req, streamToWs(req, ws), streamWsEnd(req, ws), false, true);
|
||||||
streamFrom(`chat_messages:${req.chatConversationId}`, req, streamToWs(req, ws), streamWsEnd(req, ws), false, true);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ws.close();
|
ws.close();
|
||||||
|
Loading…
Reference in New Issue
Block a user