mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-02-22 15:15:12 +08:00
perf(message-store): Debounce reload of the message column—#249
This commit is contained in:
parent
795c4f7c80
commit
25ffea50f9
2 changed files with 69 additions and 8 deletions
|
@ -12,9 +12,50 @@ testMessage1 = new Message(id: 'a', body: '123', files: [])
|
|||
testMessage2 = new Message(id: 'b', body: '123', files: [])
|
||||
|
||||
describe "MessageStore", ->
|
||||
describe "when thread focus changes", ->
|
||||
describe "when the receiving focus changes from the FocusedContentStore", ->
|
||||
beforeEach ->
|
||||
if MessageStore._onFocusChangedTimer
|
||||
clearTimeout(MessageStore._onFocusChangedTimer)
|
||||
MessageStore._onFocusChangedTimer = null
|
||||
spyOn(MessageStore, '_onApplyFocusChange')
|
||||
|
||||
afterEach ->
|
||||
if MessageStore._onFocusChangedTimer
|
||||
clearTimeout(MessageStore._onFocusChangedTimer)
|
||||
MessageStore._onFocusChangedTimer = null
|
||||
|
||||
describe "if no change has happened in the last 100ms", ->
|
||||
it "should apply immediately", ->
|
||||
FocusedContentStore.trigger(impactsCollection: (c) -> true )
|
||||
expect(MessageStore._onApplyFocusChange).toHaveBeenCalled()
|
||||
|
||||
describe "if a change has happened in the last 100ms", ->
|
||||
it "should not apply immediately", ->
|
||||
noop = =>
|
||||
MessageStore._onFocusChangedTimer = setTimeout(noop, 100)
|
||||
FocusedContentStore.trigger(impactsCollection: (c) -> true )
|
||||
expect(MessageStore._onApplyFocusChange).not.toHaveBeenCalled()
|
||||
|
||||
it "should apply 100ms after the last focus change and reset", ->
|
||||
FocusedContentStore.trigger(impactsCollection: (c) -> true )
|
||||
expect(MessageStore._onApplyFocusChange.callCount).toBe(1)
|
||||
advanceClock(50)
|
||||
FocusedContentStore.trigger(impactsCollection: (c) -> true )
|
||||
expect(MessageStore._onApplyFocusChange.callCount).toBe(1)
|
||||
advanceClock(50)
|
||||
FocusedContentStore.trigger(impactsCollection: (c) -> true )
|
||||
expect(MessageStore._onApplyFocusChange.callCount).toBe(1)
|
||||
advanceClock(150)
|
||||
FocusedContentStore.trigger(impactsCollection: (c) -> true )
|
||||
expect(MessageStore._onApplyFocusChange.callCount).toBe(3)
|
||||
advanceClock(150)
|
||||
FocusedContentStore.trigger(impactsCollection: (c) -> true )
|
||||
expect(MessageStore._onApplyFocusChange.callCount).toBe(5)
|
||||
|
||||
describe "when applying focus changes", ->
|
||||
beforeEach ->
|
||||
MessageStore._lastLoadedThreadId = null
|
||||
|
||||
@focus = null
|
||||
spyOn(FocusedContentStore, 'focused').andCallFake (collection) =>
|
||||
if collection is 'thread'
|
||||
|
@ -37,7 +78,7 @@ describe "MessageStore", ->
|
|||
it "should retrieve the focused thread", ->
|
||||
@focus = testThread
|
||||
MessageStore._thread = null
|
||||
FocusedContentStore.trigger({impactsCollection: -> true})
|
||||
MessageStore._onApplyFocusChange()
|
||||
expect(DatabaseStore.findAll).toHaveBeenCalled()
|
||||
expect(DatabaseStore.findAll.mostRecentCall.args[0]).toBe(Message)
|
||||
|
||||
|
@ -45,13 +86,13 @@ describe "MessageStore", ->
|
|||
it "should do nothing", ->
|
||||
@focus = testThread
|
||||
MessageStore._thread = @focus
|
||||
FocusedContentStore.trigger({impactsCollection: -> true})
|
||||
MessageStore._onApplyFocusChange()
|
||||
expect(DatabaseStore.findAll).not.toHaveBeenCalled()
|
||||
|
||||
describe "when the thread is unread", ->
|
||||
beforeEach ->
|
||||
@focus = null
|
||||
FocusedContentStore.trigger({impactsCollection: -> true})
|
||||
MessageStore._onApplyFocusChange()
|
||||
testThread.unread = true
|
||||
spyOn(Actions, 'queueTask')
|
||||
spyOn(atom.config, 'get').andCallFake (key) =>
|
||||
|
@ -60,7 +101,7 @@ describe "MessageStore", ->
|
|||
|
||||
it "should queue a task to mark the thread as read", ->
|
||||
@focus = testThread
|
||||
FocusedContentStore.trigger({impactsCollection: -> true})
|
||||
MessageStore._onApplyFocusChange()
|
||||
advanceClock(500)
|
||||
expect(Actions.queueTask).not.toHaveBeenCalled()
|
||||
advanceClock(500)
|
||||
|
@ -69,18 +110,18 @@ describe "MessageStore", ->
|
|||
|
||||
it "should not queue a task to mark the thread as read if the thread is no longer selected 500msec later", ->
|
||||
@focus = testThread
|
||||
FocusedContentStore.trigger({impactsCollection: -> true})
|
||||
MessageStore._onApplyFocusChange()
|
||||
advanceClock(500)
|
||||
expect(Actions.queueTask).not.toHaveBeenCalled()
|
||||
@focus = null
|
||||
FocusedContentStore.trigger({impactsCollection: -> true})
|
||||
MessageStore._onApplyFocusChange()
|
||||
advanceClock(500)
|
||||
expect(Actions.queueTask).not.toHaveBeenCalled()
|
||||
|
||||
it "should not re-mark the thread as read when made unread", ->
|
||||
@focus = testThread
|
||||
testThread.unread = false
|
||||
FocusedContentStore.trigger({impactsCollection: -> true})
|
||||
MessageStore._onApplyFocusChange()
|
||||
advanceClock(500)
|
||||
expect(Actions.queueTask).not.toHaveBeenCalled()
|
||||
|
||||
|
|
|
@ -115,6 +115,26 @@ class MessageStore extends NylasStore
|
|||
@_fetchFromCache()
|
||||
|
||||
_onFocusChanged: (change) =>
|
||||
# This implements a debounce that fires on the leading and trailing edge.
|
||||
#
|
||||
# If we haven't changed focus in the last 100ms, do it immediately. This means
|
||||
# there is no delay when moving to the next thread, deselecting a thread, etc.
|
||||
#
|
||||
# If we have changed focus in the last 100ms, wait for focus changes to
|
||||
# stop arriving for 100msec before applying. This means that flying
|
||||
# through threads doesn't cause is to make a zillion queries for messages.
|
||||
#
|
||||
if not @_onFocusChangedTimer
|
||||
@_onApplyFocusChange()
|
||||
else
|
||||
clearTimeout(@_onFocusChangedTimer)
|
||||
|
||||
@_onFocusChangedTimer = setTimeout =>
|
||||
@_onFocusChangedTimer = null
|
||||
@_onApplyFocusChange()
|
||||
, 100
|
||||
|
||||
_onApplyFocusChange: =>
|
||||
focused = FocusedContentStore.focused('thread')
|
||||
return if @_thread?.id is focused?.id
|
||||
|
||||
|
|
Loading…
Reference in a new issue