Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F32089176
composed-message.react.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
composed-message.react.js
View Options
// @flow
import
classNames
from
'classnames'
;
import
*
as
React
from
'react'
;
import
{
Circle
as
CircleIcon
,
CheckCircle
as
CheckCircleIcon
,
XCircle
as
XCircleIcon
,
}
from
'react-feather'
;
import
{
useStringForUser
}
from
'lib/hooks/ens-cache.js'
;
import
{
type
ChatMessageInfoItem
}
from
'lib/selectors/chat-selectors.js'
;
import
{
getMessageLabel
}
from
'lib/shared/edit-messages-utils.js'
;
import
{
assertComposableMessageType
}
from
'lib/types/message-types.js'
;
import
type
{
MinimallyEncodedThreadInfo
}
from
'lib/types/minimally-encoded-thread-permissions-types.js'
;
import
{
type
ThreadInfo
}
from
'lib/types/thread-types.js'
;
import
{
getComposedMessageID
}
from
'./chat-constants.js'
;
import
css
from
'./chat-message-list.css'
;
import
FailedSend
from
'./failed-send.react.js'
;
import
InlineEngagement
from
'./inline-engagement.react.js'
;
import
UserAvatar
from
'../avatars/user-avatar.react.js'
;
import
CommIcon
from
'../CommIcon.react.js'
;
import
{
type
InputState
,
InputStateContext
}
from
'../input/input-state.js'
;
import
{
usePushUserProfileModal
}
from
'../modals/user-profile/user-profile-utils.js'
;
import
{
useMessageTooltip
}
from
'../utils/tooltip-action-utils.js'
;
import
{
tooltipPositions
}
from
'../utils/tooltip-utils.js'
;
export
type
ComposedMessageID
=
string
;
const
availableTooltipPositionsForViewerMessage
=
[
tooltipPositions
.
LEFT
,
tooltipPositions
.
LEFT_BOTTOM
,
tooltipPositions
.
LEFT_TOP
,
tooltipPositions
.
RIGHT
,
tooltipPositions
.
RIGHT_BOTTOM
,
tooltipPositions
.
RIGHT_TOP
,
tooltipPositions
.
BOTTOM
,
tooltipPositions
.
TOP
,
];
const
availableTooltipPositionsForNonViewerMessage
=
[
tooltipPositions
.
RIGHT
,
tooltipPositions
.
RIGHT_BOTTOM
,
tooltipPositions
.
RIGHT_TOP
,
tooltipPositions
.
LEFT
,
tooltipPositions
.
LEFT_BOTTOM
,
tooltipPositions
.
LEFT_TOP
,
tooltipPositions
.
BOTTOM
,
tooltipPositions
.
TOP
,
];
type
BaseProps
=
{
+
item
:
ChatMessageInfoItem
,
+
threadInfo
:
ThreadInfo
|
MinimallyEncodedThreadInfo
,
+
shouldDisplayPinIndicator
:
boolean
,
+
sendFailed
:
boolean
,
+
children
:
React
.
Node
,
+
fixedWidth
?:
boolean
,
+
borderRadius
:
number
,
};
type
DefaultProps
=
{
+
borderRadius
:
number
};
type
BaseConfig
=
React
.
Config
<
BaseProps
,
DefaultProps
>
;
type
Props
=
{
...
BaseProps
,
// withInputState
+
inputState
:
?
InputState
,
+
onMouseLeave
:
?
()
=>
mixed
,
+
onMouseEnter
:
(
event
:
SyntheticEvent
<
HTMLDivElement
>
)
=>
mixed
,
+
containsInlineEngagement
:
boolean
,
+
stringForUser
:
?
string
,
+
onClickUser
:
()
=>
mixed
,
};
class
ComposedMessage
extends
React
.
PureComponent
<
Props
>
{
static
defaultProps
:
DefaultProps
=
{
borderRadius
:
8
};
render
()
:
React
.
Node
{
assertComposableMessageType
(
this
.
props
.
item
.
messageInfo
.
type
);
const
{
borderRadius
,
item
,
threadInfo
,
shouldDisplayPinIndicator
}
=
this
.
props
;
const
{
hasBeenEdited
,
isPinned
}
=
item
;
const
{
id
,
creator
}
=
item
.
messageInfo
;
const
threadColor
=
threadInfo
.
color
;
const
{
isViewer
}
=
creator
;
const
contentClassName
=
classNames
({
[
css
.
content
]
:
true
,
[
css
.
viewerContent
]
:
isViewer
,
[
css
.
nonViewerContent
]
:
!
isViewer
,
});
const
messageBoxContainerClassName
=
classNames
({
[
css
.
messageBoxContainer
]
:
true
,
[
css
.
fixedWidthMessageBoxContainer
]
:
this
.
props
.
fixedWidth
,
});
const
messageBoxClassName
=
classNames
({
[
css
.
messageBox
]
:
true
,
[
css
.
fixedWidthMessageBox
]
:
this
.
props
.
fixedWidth
,
});
const
messageBoxStyle
=
{
borderTopRightRadius
:
isViewer
&&
!
item
.
startsCluster
?
0
:
borderRadius
,
borderBottomRightRadius
:
isViewer
&&
!
item
.
endsCluster
?
0
:
borderRadius
,
borderTopLeftRadius
:
!
isViewer
&&
!
item
.
startsCluster
?
0
:
borderRadius
,
borderBottomLeftRadius
:
!
isViewer
&&
!
item
.
endsCluster
?
0
:
borderRadius
,
};
let
authorName
=
null
;
const
{
stringForUser
}
=
this
.
props
;
if
(
stringForUser
)
{
authorName
=
(
<
span
className
=
{
css
.
authorName
}
onClick
=
{
this
.
props
.
onClickUser
}
>
{
stringForUser
}
<
/span>
);
}
let
deliveryIcon
=
null
;
let
failedSendInfo
=
null
;
if
(
isViewer
)
{
let
deliveryIconSpan
;
let
deliveryIconColor
=
threadColor
;
if
(
id
!==
null
&&
id
!==
undefined
)
{
deliveryIconSpan
=
<
CheckCircleIcon
/>
;
}
else
if
(
this
.
props
.
sendFailed
)
{
deliveryIconSpan
=
<
XCircleIcon
/>
;
deliveryIconColor
=
'FF0000'
;
failedSendInfo
=
<
FailedSend
item
=
{
item
}
threadInfo
=
{
threadInfo
}
/>
;
}
else
{
deliveryIconSpan
=
<
CircleIcon
/>
;
}
deliveryIcon
=
(
<
div
className
=
{
css
.
iconContainer
}
style
=
{{
color
:
`#
${
deliveryIconColor
}
`
}}
>
{
deliveryIconSpan
}
<
/div>
);
}
let
inlineEngagement
=
null
;
const
label
=
getMessageLabel
(
hasBeenEdited
,
threadInfo
.
id
);
if
(
(
this
.
props
.
containsInlineEngagement
&&
item
.
threadCreatedFromMessage
)
||
Object
.
keys
(
item
.
reactions
).
length
>
0
||
label
)
{
const
positioning
=
isViewer
?
'right'
:
'left'
;
inlineEngagement
=
(
<
div
className
=
{
css
.
sidebarMarginBottom
}
>
<
InlineEngagement
messageInfo
=
{
item
.
messageInfo
}
threadInfo
=
{
threadInfo
}
sidebarThreadInfo
=
{
item
.
threadCreatedFromMessage
}
reactions
=
{
item
.
reactions
}
positioning
=
{
positioning
}
label
=
{
label
}
/>
<
/div>
);
}
let
avatar
;
if
(
!
isViewer
&&
item
.
endsCluster
)
{
avatar
=
(
<
div
className
=
{
css
.
avatarContainer
}
onClick
=
{
this
.
props
.
onClickUser
}
>
<
UserAvatar
size
=
"S"
userID
=
{
creator
.
id
}
/>
<
/div>
);
}
else
if
(
!
isViewer
)
{
avatar
=
<
div
className
=
{
css
.
avatarOffset
}
/>
;
}
const
pinIconPositioning
=
isViewer
?
'left'
:
'right'
;
const
pinIconName
=
pinIconPositioning
===
'left'
?
'pin-mirror'
:
'pin'
;
const
pinIconContainerClassName
=
classNames
({
[
css
.
pinIconContainer
]
:
true
,
[
css
.
pinIconLeft
]
:
pinIconPositioning
===
'left'
,
[
css
.
pinIconRight
]
:
pinIconPositioning
===
'right'
,
});
let
pinIcon
;
if
(
isPinned
&&
shouldDisplayPinIndicator
)
{
pinIcon
=
(
<
div
className
=
{
pinIconContainerClassName
}
style
=
{{
color
:
`#
${
threadColor
}
`
}}
>
<
CommIcon
icon
=
{
pinIconName
}
size
=
{
12
}
/>
<
/div>
);
}
return
(
<
React
.
Fragment
>
{
authorName
}
<
div
className
=
{
contentClassName
}
>
{
avatar
}
<
div
className
=
{
messageBoxContainerClassName
}
onMouseEnter
=
{
this
.
props
.
onMouseEnter
}
onMouseLeave
=
{
this
.
props
.
onMouseLeave
}
>
{
pinIcon
}
<
div
className
=
{
messageBoxClassName
}
style
=
{
messageBoxStyle
}
id
=
{
getComposedMessageID
(
item
.
messageInfo
)}
>
{
this
.
props
.
children
}
<
/div>
<
/div>
{
deliveryIcon
}
<
/div>
{
failedSendInfo
}
{
inlineEngagement
}
<
/React.Fragment>
);
}
}
type
ConnectedConfig
=
React
.
Config
<
BaseProps
,
typeof
ComposedMessage
.
defaultProps
,
>
;
const
ConnectedComposedMessage
:
React
.
ComponentType
<
ConnectedConfig
>
=
React
.
memo
<
BaseConfig
>
(
function
ConnectedComposedMessage
(
props
)
{
const
{
item
,
threadInfo
}
=
props
;
const
inputState
=
React
.
useContext
(
InputStateContext
);
const
{
creator
}
=
props
.
item
.
messageInfo
;
const
{
isViewer
}
=
creator
;
const
availablePositions
=
isViewer
?
availableTooltipPositionsForViewerMessage
:
availableTooltipPositionsForNonViewerMessage
;
const
containsInlineEngagement
=
!!
item
.
threadCreatedFromMessage
;
const
{
onMouseLeave
,
onMouseEnter
}
=
useMessageTooltip
({
item
,
threadInfo
,
availablePositions
,
});
const
shouldShowUsername
=
!
isViewer
&&
item
.
startsCluster
;
const
stringForUser
=
useStringForUser
(
shouldShowUsername
?
creator
:
null
);
const
pushUserProfileModal
=
usePushUserProfileModal
(
creator
.
id
);
return
(
<
ComposedMessage
{...
props
}
inputState
=
{
inputState
}
onMouseLeave
=
{
onMouseLeave
}
onMouseEnter
=
{
onMouseEnter
}
containsInlineEngagement
=
{
containsInlineEngagement
}
stringForUser
=
{
stringForUser
}
onClickUser
=
{
pushUserProfileModal
}
/>
);
});
export
default
ConnectedComposedMessage
;
File Metadata
Details
Attached
Mime Type
text/x-java
Expires
Sun, Dec 7, 7:56 AM (4 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5834118
Default Alt Text
composed-message.react.js (8 KB)
Attached To
Mode
rCOMM Comm
Attached
Detach File
Event Timeline
Log In to Comment