fix(composer): composer doesn't jump with attachments

Summary: Fixes T3778

Test Plan: manual

Reviewers: bengotow

Reviewed By: bengotow

Projects: #edgehill

Maniphest Tasks: T3778

Differential Revision: https://phab.nylas.com/D2102
This commit is contained in:
Evan Morikawa 2015-10-02 17:14:00 -07:00
parent 609b6107f9
commit 71e90d2a61
3 changed files with 38 additions and 6 deletions

View file

@ -153,11 +153,13 @@ class ComposerView extends React.Component
render: =>
if @props.mode is "inline"
<FocusTrackingRegion className={@_wrapClasses()} tabIndex="-1">
<FocusTrackingRegion className={@_wrapClasses()}
ref="composer"
tabIndex="-1">
{@_renderComposer()}
</FocusTrackingRegion>
else
<div className={@_wrapClasses()}>
<div className={@_wrapClasses()} ref="composer">
{@_renderComposer()}
</div>
@ -283,12 +285,22 @@ class ComposerView extends React.Component
onFilePaste={@_onFilePaste}
footerElements={@_editableFooterElements()}
onScrollToBottom={@_onScrollToBottom()}
getComposerBoundingRect={@_getComposerBoundingRect}
initialSelectionSnapshot={@_recoveredSelection} />
# The contenteditable decides when to request a scroll based on the
# position of the cursor and its relative distance to this composer
# component. We provide it our boundingClientRect so it can calculate
# this value.
_getComposerBoundingRect: =>
React.findDOMNode(@refs.composer).getBoundingClientRect()
_onScrollToBottom: ->
if @props.onRequestScrollTo
return =>
@props.onRequestScrollTo({clientId: @_proxy.draft().clientId})
@props.onRequestScrollTo
clientId: @_proxy.draft().clientId
position: ScrollRegion.ScrollPosition.Bottom
else return null
_editableFilters: ->

View file

@ -607,7 +607,7 @@ class ContenteditableComponent extends React.Component
# the scroll container may be many levels up.
_ensureSelectionVisible: (selection) ->
# If our parent supports scroll to bottom, check for that
if @props.onScrollToBottom and DOMUtils.atEndOfContent(selection, @_editableNode())
if @_shouldScrollToBottom(selection)
@props.onScrollToBottom()
# Don't bother computing client rects if no scroll method has been provided
@ -625,6 +625,25 @@ class ContenteditableComponent extends React.Component
# The bounding client rect has changed
@setInnerState editableNode: @_editableNode()
# As you're typing a lot of content and the cursor begins to scroll off
# to the bottom, we want to make it look like we're tracking your
# typing.
_shouldScrollToBottom: (selection) ->
(@props.onScrollToBottom and
DOMUtils.atEndOfContent(selection, @_editableNode()) and
@_bottomIsNearby())
# If the bottom of the container we're scrolling to is really far away
# from this contenteditable and your scroll position, we don't want to
# jump away. This can commonly happen if the composer has a very tall
# image attachment. The "send" button may be 1000px away from the bottom
# of the contenteditable. props.onScrollToBottom moves to the bottom of
# the "send" button.
_bottomIsNearby: ->
parentRect = @props.getComposerBoundingRect()
selfRect = @_editableNode().getBoundingClientRect()
return Math.abs(parentRect.bottom - selfRect.bottom) <= 250
_getSelectionRectFromDOM: (selection) ->
node = selection.anchorNode
if node.nodeType is Node.TEXT_NODE

View file

@ -358,13 +358,14 @@ class MessageList extends React.Component
#
# If messageId and location are defined, that means we want to scroll
# smoothly to the top of a particular message.
_onChildScrollRequest: ({clientId, rect}={}) =>
_onChildScrollRequest: ({clientId, rect, position}={}) =>
return if @_draftScrollInProgress
if clientId
messageElement = @_getMessageContainer(clientId)
return unless messageElement
pos = position ? ScrollRegion.ScrollPosition.Visible
@refs.messageWrap.scrollTo(messageElement, {
position: ScrollRegion.ScrollPosition.Visible
position: pos
})
else if rect
@refs.messageWrap.scrollToRect(rect, {