From d5eb68ece1ddb97c9b8b8ed16fdc6fbc1af27d8b Mon Sep 17 00:00:00 2001 From: Evan Morikawa Date: Tue, 10 Mar 2015 13:15:28 -0700 Subject: [PATCH] fix(scrolling): scroll to end once. Fix draft deletion --- .../lib/account-sidebar-tag-item.cjsx | 4 +- .../message-list/lib/message-list.cjsx | 38 ++++++++++++------- .../message-list/spec/message-list-spec.cjsx | 4 +- .../thread-list/lib/draft-list.cjsx | 6 +-- src/components/list-tabular.cjsx | 8 +++- src/flux/stores/draft-store.coffee | 1 + src/flux/tasks/destroy-draft.coffee | 5 +-- 7 files changed, 41 insertions(+), 25 deletions(-) diff --git a/internal_packages/account-sidebar/lib/account-sidebar-tag-item.cjsx b/internal_packages/account-sidebar/lib/account-sidebar-tag-item.cjsx index 4705782f3..1ee4fee48 100644 --- a/internal_packages/account-sidebar/lib/account-sidebar-tag-item.cjsx +++ b/internal_packages/account-sidebar/lib/account-sidebar-tag-item.cjsx @@ -9,6 +9,8 @@ AccountSidebarTagItem = React.createClass if @props.tag.unreadCount > 0 unread =
{@props.tag.unreadCount}
+ 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
{unread} - {@props.tag.name} + {name}
_onClick: (event) -> diff --git a/internal_packages/message-list/lib/message-list.cjsx b/internal_packages/message-list/lib/message-list.cjsx index 647b44110..9bca3f514 100755 --- a/internal_packages/message-list/lib/message-list.cjsx +++ b/internal_packages/message-list/lib/message-list.cjsx @@ -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
if not @state.current_thread? + return
if not @state.currentThread?
@@ -58,7 +70,7 @@ MessageList = React.createClass _messageListNotificationBars: -> MLBars = ComponentRegistry.findAllViewsByRole('MessageListNotificationBar')
- { for MLBar in MLBars} + { for MLBar in MLBars}
_messageListHeaders: -> @@ -66,10 +78,10 @@ MessageList = React.createClass MessageListHeaders = ComponentRegistry.findAllViewsByRole('MessageListHeader')
-

{@state.current_thread.subject}

+

{@state.currentThread.subject}

{for MessageListHeader in MessageListHeaders - + }
@@ -103,7 +115,7 @@ MessageList = React.createClass className = "message-item-wrap" if message.unread then className += " unread-message" components.push 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 = {} diff --git a/internal_packages/message-list/spec/message-list-spec.cjsx b/internal_packages/message-list/spec/message-list-spec.cjsx index 97f5f2c40..8aea98a25 100644 --- a/internal_packages/message-list/spec/message-list-spec.cjsx +++ b/internal_packages/message-list/spec/message-list-spec.cjsx @@ -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, diff --git a/internal_packages/thread-list/lib/draft-list.cjsx b/internal_packages/thread-list/lib/draft-list.cjsx index b10ee7db7..c2b5b3492 100644 --- a/internal_packages/thread-list/lib/draft-list.cjsx +++ b/internal_packages/thread-list/lib/draft-list.cjsx @@ -37,15 +37,15 @@ DraftList = React.createClass columns={@state.columns} items={@state.items} selectedId={@state.selectedId} - onDoubleClick={@_onDoubleClick} + onClick={@_onClick} onSelect={@_onSelect} />
- + _onSelect: (item) -> @setState selectedId: item.id - _onDoubleClick: (item) -> + _onClick: (item) -> DatabaseStore.localIdForModel(item).then (localId) -> Actions.composePopoutDraft(localId) diff --git a/src/components/list-tabular.cjsx b/src/components/list-tabular.cjsx index efe9cbbf0..9e2971209 100644 --- a/src/components/list-tabular.cjsx +++ b/src/components/list-tabular.cjsx @@ -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, @)}
- + _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} /> diff --git a/src/flux/stores/draft-store.coffee b/src/flux/stores/draft-store.coffee index 73caf0508..b434f6422 100644 --- a/src/flux/stores/draft-store.coffee +++ b/src/flux/stores/draft-store.coffee @@ -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] diff --git a/src/flux/tasks/destroy-draft.coffee b/src/flux/tasks/destroy-draft.coffee index c15a13fc4..66fb04d92 100644 --- a/src/flux/tasks/destroy-draft.coffee +++ b/src/flux/tasks/destroy-draft.coffee @@ -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()