mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-11-08 07:21:18 +08:00
fix(scrolling): scroll to end once. Fix draft deletion
This commit is contained in:
parent
6af864e3bd
commit
d5eb68ece1
7 changed files with 41 additions and 25 deletions
|
|
@ -9,6 +9,8 @@ AccountSidebarTagItem = React.createClass
|
|||
if @props.tag.unreadCount > 0
|
||||
unread = <div className="unread item-count-box">{@props.tag.unreadCount}</div>
|
||||
|
||||
name = if @props.tag.name is "drafts" then "Local Drafts" else @props.tag.name
|
||||
|
||||
classSet = React.addons.classSet
|
||||
'item': true
|
||||
'item-tag': true
|
||||
|
|
@ -17,7 +19,7 @@ AccountSidebarTagItem = React.createClass
|
|||
<div className={classSet} onClick={@_onClick} id={@props.tag.id}>
|
||||
{unread}
|
||||
<RetinaImg name={"#{@props.tag.id}.png"} fallback={'folder.png'} selected={@props.select}/>
|
||||
<span className="name"> {@props.tag.name}</span>
|
||||
<span className="name"> {name}</span>
|
||||
</div>
|
||||
|
||||
_onClick: (event) ->
|
||||
|
|
|
|||
|
|
@ -27,12 +27,24 @@ MessageList = React.createClass
|
|||
if newDrafts.length >= 1
|
||||
@_focusComposerId = newDrafts[0]
|
||||
|
||||
componentDidUpdate: ->
|
||||
@_lastHeight = -1
|
||||
@_scrollToBottom()
|
||||
if @_focusComposerId?
|
||||
@_focusRef(@refs["composerItem-#{@_focusComposerId}"])
|
||||
@_focusComposerId = null
|
||||
componentDidUpdate: (prevProps, prevState) ->
|
||||
if @_shouldScroll(prevState)
|
||||
@_lastHeight = -1
|
||||
@_scrollToBottom()
|
||||
if @_focusComposerId?
|
||||
@_focusRef(@refs["composerItem-#{@_focusComposerId}"])
|
||||
@_focusComposerId = null
|
||||
|
||||
# Only scroll if the messages change and there are some message
|
||||
_shouldScroll: (prevState) ->
|
||||
return false if (@state.messages ? []).length is 0
|
||||
prevMsg = (prevState.messages ? []).map((m) -> m.id)
|
||||
curMsg = (@state.messages ? []).map((m) -> m.id)
|
||||
return true if prevMsg.length isnt curMsg.length
|
||||
iLength = _.intersection(prevMsg, curMsg).length
|
||||
return true if iLength isnt prevMsg.length or iLength isnt curMsg.length
|
||||
return false
|
||||
|
||||
|
||||
# We need a 100ms delay so the DOM can finish painting the elements on
|
||||
# the page. The focus doesn't work for some reason while the paint is in
|
||||
|
|
@ -42,7 +54,7 @@ MessageList = React.createClass
|
|||
, 100
|
||||
|
||||
render: ->
|
||||
return <div></div> if not @state.current_thread?
|
||||
return <div></div> if not @state.currentThread?
|
||||
|
||||
<div className="message-list" id="message-list">
|
||||
<div tabIndex=1 ref="messageWrap" className="messages-wrap">
|
||||
|
|
@ -58,7 +70,7 @@ MessageList = React.createClass
|
|||
_messageListNotificationBars: ->
|
||||
MLBars = ComponentRegistry.findAllViewsByRole('MessageListNotificationBar')
|
||||
<div className="message-list-notification-bar-wrap">
|
||||
{<MLBar thread={@state.current_thread} /> for MLBar in MLBars}
|
||||
{<MLBar thread={@state.currentThread} /> for MLBar in MLBars}
|
||||
</div>
|
||||
|
||||
_messageListHeaders: ->
|
||||
|
|
@ -66,10 +78,10 @@ MessageList = React.createClass
|
|||
MessageListHeaders = ComponentRegistry.findAllViewsByRole('MessageListHeader')
|
||||
|
||||
<div className="message-list-headers">
|
||||
<h2 className="message-subject">{@state.current_thread.subject}</h2>
|
||||
<h2 className="message-subject">{@state.currentThread.subject}</h2>
|
||||
|
||||
{for MessageListHeader in MessageListHeaders
|
||||
<MessageListHeader thread={@state.current_thread} />
|
||||
<MessageListHeader thread={@state.currentThread} />
|
||||
}
|
||||
</div>
|
||||
|
||||
|
|
@ -103,7 +115,7 @@ MessageList = React.createClass
|
|||
className = "message-item-wrap"
|
||||
if message.unread then className += " unread-message"
|
||||
components.push <MessageItem key={message.id}
|
||||
thread={@state.current_thread}
|
||||
thread={@state.currentThread}
|
||||
message={message}
|
||||
collapsed={collapsed}
|
||||
className={className}
|
||||
|
|
@ -117,11 +129,11 @@ MessageList = React.createClass
|
|||
_getStateFromStores: ->
|
||||
messages: (MessageStore.items() ? [])
|
||||
messageLocalIds: MessageStore.itemLocalIds()
|
||||
current_thread: ThreadStore.selectedThread()
|
||||
currentThread: ThreadStore.selectedThread()
|
||||
|
||||
_threadParticipants: ->
|
||||
# We calculate the list of participants instead of grabbing it from
|
||||
# `@state.current_thread.participants` because it makes it easier to
|
||||
# `@state.currentThread.participants` because it makes it easier to
|
||||
# test, is a better source of ground truth, and saves us from more
|
||||
# dependencies.
|
||||
participants = {}
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ describe "MessageList", ->
|
|||
beforeEach ->
|
||||
MessageStore._items = testMessages
|
||||
MessageStore.trigger(MessageStore)
|
||||
@message_list.setState current_thread: test_thread
|
||||
@message_list.setState currentThread: test_thread
|
||||
|
||||
it "renders all the correct number of messages", ->
|
||||
items = TestUtils.scryRenderedComponentsWithType(@message_list,
|
||||
|
|
@ -268,7 +268,7 @@ describe "MessageList", ->
|
|||
beforeEach ->
|
||||
MessageStore._items = testMessages.concat draftMessages
|
||||
MessageStore.trigger(MessageStore)
|
||||
@message_list.setState current_thread: test_thread
|
||||
@message_list.setState currentThread: test_thread
|
||||
|
||||
it "renders the composer", ->
|
||||
items = TestUtils.scryRenderedComponentsWithType(@message_list,
|
||||
|
|
|
|||
|
|
@ -37,15 +37,15 @@ DraftList = React.createClass
|
|||
columns={@state.columns}
|
||||
items={@state.items}
|
||||
selectedId={@state.selectedId}
|
||||
onDoubleClick={@_onDoubleClick}
|
||||
onClick={@_onClick}
|
||||
onSelect={@_onSelect} />
|
||||
</div>
|
||||
|
||||
|
||||
_onSelect: (item) ->
|
||||
@setState
|
||||
selectedId: item.id
|
||||
|
||||
_onDoubleClick: (item) ->
|
||||
_onClick: (item) ->
|
||||
DatabaseStore.localIdForModel(item).then (localId) ->
|
||||
Actions.composePopoutDraft(localId)
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ ListTabularItem = React.createClass
|
|||
itemClassProvider: React.PropTypes.func
|
||||
displayHeaders: React.PropTypes.bool
|
||||
onSelect: React.PropTypes.func
|
||||
onClick: React.PropTypes.func
|
||||
onDoubleClick: React.PropTypes.func
|
||||
|
||||
# DO NOT DELETE unless you know what you're doing! This method cuts
|
||||
|
|
@ -32,14 +33,15 @@ ListTabularItem = React.createClass
|
|||
className="list-column">
|
||||
{column.resolver(@props.item, @)}
|
||||
</div>
|
||||
|
||||
|
||||
_onClick: ->
|
||||
if not @props.selected
|
||||
@props.onSelect?(@props.item)
|
||||
|
||||
@props.onClick?(@props.item)
|
||||
if @_lastClickTime? and Date.now() - @_lastClickTime < 350
|
||||
@props.onDoubleClick?(@props.item)
|
||||
|
||||
|
||||
@_lastClickTime = Date.now()
|
||||
|
||||
_containerClasses: ->
|
||||
|
|
@ -60,6 +62,7 @@ ListTabular = React.createClass
|
|||
itemClassProvider: React.PropTypes.func
|
||||
selectedId: React.PropTypes.string
|
||||
onSelect: React.PropTypes.func
|
||||
onClick: React.PropTypes.func
|
||||
onDoubleClick: React.PropTypes.func
|
||||
|
||||
render: ->
|
||||
|
|
@ -92,6 +95,7 @@ ListTabular = React.createClass
|
|||
itemClassProvider={@props.itemClassProvider}
|
||||
columns={@props.columns}
|
||||
onSelect={@props.onSelect}
|
||||
onClick={@props.onClick}
|
||||
onDoubleClick={@props.onDoubleClick} />
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -179,6 +179,7 @@ DraftStore = Reflux.createStore
|
|||
|
||||
_onDestroyDraft: (draftLocalId) ->
|
||||
# Immediately reset any pending changes so no saves occur
|
||||
@_closeWindow(draftLocalId)
|
||||
@_draftSessions[draftLocalId]?.changes.reset()
|
||||
delete @_draftSessions[draftLocalId]
|
||||
|
||||
|
|
|
|||
|
|
@ -42,9 +42,7 @@ class DestroyDraftTask extends Task
|
|||
body:
|
||||
version: @draft.version
|
||||
returnsModel: false
|
||||
success: (args...) =>
|
||||
Actions.destroyDraftSuccess(@draftLocalId)
|
||||
resolve(args...)
|
||||
success: resolve
|
||||
error: reject
|
||||
|
||||
onAPIError: (apiError) ->
|
||||
|
|
@ -57,7 +55,6 @@ class DestroyDraftTask extends Task
|
|||
# do but finish
|
||||
return true
|
||||
else
|
||||
Actions.destroyDraftError(@draftLocalId)
|
||||
@_rollbackLocal()
|
||||
|
||||
onOtherError: -> Promise.resolve()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue