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:
Evan Morikawa 2015-10-22 14:14:58 -07:00
parent c5b9f6a634
commit cfb4142471
4 changed files with 22 additions and 162 deletions

View file

@ -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

View file

@ -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'

View file

@ -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()

View file

@ -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'