mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-02-21 14:46:31 +08:00
fix(event): remove EventStore
Summary: The EventStore was really doing nothing, except caching hundreds of MB of event data unnecessarily in each and every window :( Test Plan: manual Reviewers: bengotow Reviewed By: bengotow Differential Revision: https://phab.nylas.com/D2187
This commit is contained in:
parent
c5b9f6a634
commit
cfb4142471
4 changed files with 22 additions and 162 deletions
|
@ -3,10 +3,11 @@ path = require 'path'
|
|||
React = require 'react'
|
||||
{RetinaImg} = require 'nylas-component-kit'
|
||||
{Actions,
|
||||
Event,
|
||||
Utils,
|
||||
ComponentRegistry,
|
||||
EventStore,
|
||||
AccountStore} = require 'nylas-exports'
|
||||
EventRSVPTask = require './tasks/event-rsvp'
|
||||
moment = require 'moment-timezone'
|
||||
|
||||
class EventComponent extends React.Component
|
||||
|
@ -16,20 +17,27 @@ class EventComponent extends React.Component
|
|||
event: React.PropTypes.object.isRequired
|
||||
|
||||
constructor: (@props) ->
|
||||
@state = @_getStateFromStores()
|
||||
# Since getting state is asynchronous, default to empty values
|
||||
@state = @_nullEvent()
|
||||
|
||||
_nullEvent: ->
|
||||
participants: []
|
||||
title: ""
|
||||
when: {start_time: 0}
|
||||
|
||||
_onChange: =>
|
||||
@setState(@_getStateFromStores())
|
||||
DatabaseStore.find(Event, @props.event.id).then (event) =>
|
||||
event ?= @_nullEvent()
|
||||
@setState(event)
|
||||
|
||||
_getStateFromStores: ->
|
||||
e = EventStore.getEvent(@props.event.id)
|
||||
e ?= @props.event
|
||||
componentDidMount: -> @_onChange()
|
||||
|
||||
componentWillMount: ->
|
||||
@unsub = EventStore.listen(@_onChange)
|
||||
@usubs.push DatabaseStore.listen (change) =>
|
||||
@_onChange() if change.objectClass is Event.name
|
||||
@usubs.push AccountStore.listen(@_onChange)
|
||||
|
||||
componentWillUnmount: ->
|
||||
@unsub()
|
||||
componentWillUnmount: -> usub?() for usub in @usubs()
|
||||
|
||||
_myStatus: =>
|
||||
myEmail = AccountStore.current()?.me().email
|
||||
|
@ -72,7 +80,7 @@ class EventComponent extends React.Component
|
|||
classes = "btn-rsvp"
|
||||
if @_myStatus() == "yes"
|
||||
classes += " yes"
|
||||
<div className=classes onClick={@_onClickAccept}>
|
||||
<div className=classes onClick={=> @_rsvp("yes")}>
|
||||
Accept
|
||||
</div>
|
||||
|
||||
|
@ -80,7 +88,7 @@ class EventComponent extends React.Component
|
|||
classes = "btn-rsvp"
|
||||
if @_myStatus() == "no"
|
||||
classes += " no"
|
||||
<div className=classes onClick={@_onClickDecline}>
|
||||
<div className=classes onClick={=> @_rsvp("no")}>
|
||||
Decline
|
||||
</div>
|
||||
|
||||
|
@ -88,15 +96,12 @@ class EventComponent extends React.Component
|
|||
classes = "btn-rsvp"
|
||||
if @_myStatus() == "maybe"
|
||||
classes += " maybe"
|
||||
<div className=classes onClick={@_onClickMaybe}>
|
||||
<div className=classes onClick={=> @_rsvp("maybe")}>
|
||||
Maybe
|
||||
</div>
|
||||
|
||||
_onClickAccept: => Actions.RSVPEvent(@state, "yes")
|
||||
|
||||
_onClickDecline: => Actions.RSVPEvent(@state, "no")
|
||||
|
||||
_onClickMaybe: => Actions.RSVPEvent(@state, "maybe")
|
||||
_rsvp: (status) ->
|
||||
Acitions.queueTask(new EventRSVPTask(@state, status))
|
||||
|
||||
|
||||
module.exports = EventComponent
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
_ = require 'underscore'
|
||||
proxyquire = require 'proxyquire'
|
||||
Event = require '../../src/flux/models/event'
|
||||
EventStore = require '../../src/flux/stores/event-store'
|
||||
DatabaseStore = require '../../src/flux/stores/database-store'
|
||||
AccountStore = require '../../src/flux/stores/account-store'
|
||||
|
||||
describe "EventStore", ->
|
||||
beforeEach ->
|
||||
atom.testOrganizationUnit = "folder"
|
||||
EventStore._eventCache = {}
|
||||
EventStore._accountId = null
|
||||
|
||||
afterEach ->
|
||||
atom.testOrganizationUnit = null
|
||||
|
||||
it "initializes the cache from the DB", ->
|
||||
spyOn(DatabaseStore, "findAll").andCallFake -> Promise.resolve([])
|
||||
advanceClock(30)
|
||||
EventStore.constructor()
|
||||
advanceClock(30)
|
||||
expect(Object.keys(EventStore._eventCache).length).toBe 0
|
||||
expect(DatabaseStore.findAll).toHaveBeenCalled()
|
||||
|
||||
describe "when the Account updates from null to valid", ->
|
||||
beforeEach ->
|
||||
spyOn(EventStore, "_refreshCache")
|
||||
AccountStore.trigger()
|
||||
|
||||
it "triggers a database fetch", ->
|
||||
expect(EventStore._refreshCache.calls.length).toBe 1
|
||||
|
||||
describe "when the Account updates but the ID doesn't change", ->
|
||||
it "does nothing", ->
|
||||
spyOn(EventStore, "_refreshCache")
|
||||
EventStore._eventCache = {1: '', 2: '', 3: ''}
|
||||
EventStore._accountId = TEST_ACCOUNT_ID
|
||||
AccountStore.trigger()
|
||||
expect(EventStore._eventCache).toEqual {1: '', 2: '', 3: ''}
|
||||
expect(EventStore._refreshCache).not.toHaveBeenCalled()
|
||||
|
||||
describe "getEvent", ->
|
||||
beforeEach ->
|
||||
@e1 = new Event(id: 'a', title:'Test1', start: '', end: '', location: '', participants: [{"name":"Guy", "email":"tester@nylas.com", "status":"noreply"}])
|
||||
@e2 = new Event(id: 'b', title:'Test2', start: '', end: '', location: '', participants: [{"name":"Guy", "email":"tester@nylas.com", "status":"noreply"}])
|
||||
@e3 = new Event(id: 'c', title:'Test3', start: '', end: '', location: '', participants: [{"name":"Guy", "email":"tester@nylas.com", "status":"noreply"}])
|
||||
@e4 = new Event(id: 'd', title:'Test4', start: '', end: '', location: '', participants: [{"name":"Guy", "email":"tester@nylas.com", "status":"noreply"}])
|
||||
EventStore._eventCache = {}
|
||||
for e in [@e1, @e2, @e3, @e4]
|
||||
EventStore._eventCache[e.id] = e
|
||||
|
||||
it "returns event object based on id", ->
|
||||
first = EventStore.getEvent('a')
|
||||
expect(first.title).toBe 'Test1'
|
||||
second = EventStore.getEvent('b')
|
||||
expect(second.title).toBe 'Test2'
|
||||
third = EventStore.getEvent('c')
|
||||
expect(third.title).toBe 'Test3'
|
||||
fourth = EventStore.getEvent('d')
|
||||
expect(fourth.title).toBe 'Test4'
|
|
@ -1,84 +0,0 @@
|
|||
Reflux = require 'reflux'
|
||||
Actions = require '../actions'
|
||||
Event = require '../models/event'
|
||||
Utils = require '../models/utils'
|
||||
NylasStore = require 'nylas-store'
|
||||
DatabaseStore = require './database-store'
|
||||
AccountStore = require './account-store'
|
||||
_ = require 'underscore'
|
||||
|
||||
EventRSVPTask = require '../tasks/event-rsvp'
|
||||
|
||||
{Listener, Publisher} = require '../modules/reflux-coffee'
|
||||
CoffeeHelpers = require '../coffee-helpers'
|
||||
|
||||
###
|
||||
Public: EventStore maintains
|
||||
|
||||
## Listening for Changes
|
||||
|
||||
The EventStore monitors the {DatabaseStore} for changes to {Event} models
|
||||
and triggers when events have changed, allowing your stores and components
|
||||
to refresh data based on the EventStore.
|
||||
|
||||
```coffee
|
||||
@unsubscribe = EventStore.listen(@_onEventsChanged, @)
|
||||
|
||||
_onEventsChanged: ->
|
||||
# refresh your event results
|
||||
```
|
||||
|
||||
Section: Stores
|
||||
###
|
||||
class EventStore extends NylasStore
|
||||
|
||||
constructor: ->
|
||||
@_eventCache = {}
|
||||
@_accountId = AccountStore.current()?.id
|
||||
|
||||
@listenTo DatabaseStore, @_onDatabaseChanged
|
||||
@listenTo AccountStore, @_onAccountChanged
|
||||
|
||||
# From Views
|
||||
@listenTo Actions.RSVPEvent, @_onRSVPEvent
|
||||
|
||||
@__refreshCache()
|
||||
|
||||
_onRSVPEvent: (calendar_event, RSVPStatus) ->
|
||||
task = new EventRSVPTask(calendar_event, RSVPStatus)
|
||||
Actions.queueTask(task)
|
||||
|
||||
__refreshCache: =>
|
||||
return unless @_accountId
|
||||
|
||||
new Promise (resolve, reject) =>
|
||||
DatabaseStore.findAll(Event, {accountId: @_accountId}).then (events=[]) =>
|
||||
@_eventCache[e.id] = e for e in events
|
||||
@trigger()
|
||||
resolve()
|
||||
.catch (err) ->
|
||||
console.warn("Request for Events failed. #{err}")
|
||||
_refreshCache: _.debounce(EventStore::__refreshCache, 20)
|
||||
|
||||
_onDatabaseChanged: (change) =>
|
||||
return unless change?.objectClass is Event.name
|
||||
for e in change.objects
|
||||
@_eventCache[e.id] = e
|
||||
|
||||
_resetCache: =>
|
||||
@_eventCache = {}
|
||||
@trigger(@)
|
||||
|
||||
getEvent: (id) =>
|
||||
@_eventCache[id]
|
||||
|
||||
_onAccountChanged: =>
|
||||
return if @_accountId is AccountStore.current()?.id
|
||||
@_accountId = AccountStore.current()?.id
|
||||
|
||||
if @_accountId
|
||||
@_refreshCache()
|
||||
else
|
||||
@_resetCache()
|
||||
|
||||
module.exports = new EventStore()
|
|
@ -97,7 +97,6 @@ class NylasExports
|
|||
# These need to be required immediately since some Stores are
|
||||
# listen-only and not explicitly required from anywhere. Stores
|
||||
# currently set themselves up on require.
|
||||
@require "EventStore", 'flux/stores/event-store'
|
||||
@require "DraftStore", 'flux/stores/draft-store'
|
||||
@require "AccountStore", 'flux/stores/account-store'
|
||||
@require "MessageStore", 'flux/stores/message-store'
|
||||
|
|
Loading…
Reference in a new issue