Mailspring/internal_packages/thread-list/lib/empty-state.cjsx
Ben Gotow 1a576d92dc feat(work): Create the "Work" window, move TaskQueue, Nylas sync workers
Summary:
Move sync workers and Edgehill token checks to work window

Move the task queue and database setup to the work window

Move ContactStore background refresh to work window

Store the task queue in the database

WIP

The TaskQueue now puts tasks in the database instead of in a file, which also means it can be observed

Move all delta sync and initial sync to a package, make NylasSyncStore which exposes read-only sync state

DraftStore no longer reads task status. Once you set the "sending" bit on a draft, it never gets unset. But that's fine actually.

If your package lists windowTypes, you *only* get loaded in those windowTypes. If you specify no windowTypes, you get loaded in the root window.

This means that onboarding, worker-ui, worker-sync, etc. no longer get loaded into the main window

ActivitySidebar has a special little store that observes the task queue since it's no longer in the window

Move "toggle component regions" / "toggle react remote" to the Developer menu

Move sync worker specs, update draft store specs to not rely on TaskQueue at all

Test Plan: Run existing tests, all pass

Reviewers: dillon, evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D1936
2015-08-27 16:39:40 -07:00

126 lines
3.9 KiB
CoffeeScript

_ = require 'underscore'
React = require 'react'
classNames = require 'classnames'
{RetinaImg} = require 'nylas-component-kit'
{DatabaseView,
NylasAPI,
NylasSyncStatusStore,
WorkspaceStore} = require 'nylas-exports'
EmptyMessages = [{
"body":"The pessimist complains about the wind.\nThe optimist expects it to change.\nThe realist adjusts the sails."
"byline": "- William Arthur Ward"
},{
"body":"The best and most beautiful things in the world cannot be seen or even touched - they must be felt with the heart."
"byline": "- Hellen Keller"
},{
"body":"Believe you can and you're halfway there."
"byline": "- Theodore Roosevelt"
},{
"body":"Don't judge each day by the harvest you reap but by the seeds that you plant."
"byline": "- Robert Louis Stevenson"
}]
class ContentGeneric extends React.Component
render: ->
<div className="generic">
<div className="message">
{@props.messageOverride ? "No threads to display."}
</div>
</div>
class ContentQuotes extends React.Component
@displayName = 'Quotes'
constructor: (@props) ->
@state = {}
componentDidMount: ->
# Pick a random quote using the day as a seed. I know not all months have
# 31 days - this is good enough to generate one quote a day at random!
d = new Date()
r = d.getDate() + d.getMonth() * 31
message = EmptyMessages[r % EmptyMessages.length]
@setState(message: message)
render: ->
<div className="quotes">
{@_renderMessage()}
<RetinaImg mode={RetinaImg.Mode.ContentLight} url="nylas://thread-list/assets/blank-bottom-left@2x.png" className="bottom-left"/>
<RetinaImg mode={RetinaImg.Mode.ContentLight} url="nylas://thread-list/assets/blank-top-left@2x.png" className="top-left"/>
<RetinaImg mode={RetinaImg.Mode.ContentLight} url="nylas://thread-list/assets/blank-bottom-right@2x.png" className="bottom-right"/>
<RetinaImg mode={RetinaImg.Mode.ContentLight} url="nylas://thread-list/assets/blank-top-right@2x.png" className="top-right"/>
</div>
_renderMessage: ->
if @props.messageOverride
<div className="message">{@props.messageOverride}</div>
else
<div className="message">
{@state.message?.body}
<div className="byline">
{@state.message?.byline}
</div>
</div>
class EmptyState extends React.Component
@displayName = 'EmptyState'
@propTypes =
visible: React.PropTypes.bool.isRequired
dataView: React.PropTypes.object
constructor: (@props) ->
@state =
layoutMode: WorkspaceStore.layoutMode()
syncing: NylasSyncStatusStore.busy()
active: false
componentDidMount: ->
@_unlisteners = []
@_unlisteners.push WorkspaceStore.listen(@_onChange, @)
@_unlisteners.push NylasSyncStatusStore.listen(@_onChange, @)
shouldComponentUpdate: (nextProps, nextState) ->
# Avoid deep comparison of dataView, which is a very complex object
return true if nextProps.visible isnt @props.visible
return true if nextProps.dataView isnt @props.dataView
return not _.isEqual(nextState, @state)
componentWillUnmount: ->
unlisten() for unlisten in @_unlisteners
componentDidUpdate: ->
if @props.visible and not @state.active
@setState(active:true)
componentWillReceiveProps: (newProps) ->
if newProps.visible is false
@setState(active:false)
render: ->
ContentComponent = ContentGeneric
messageOverride = null
if @props.dataView instanceof DatabaseView
if @state.layoutMode is 'list'
ContentComponent = ContentQuotes
if @state.syncing
messageOverride = "Please wait while we prepare your mailbox."
classes = classNames
'empty-state': true
'visible': @props.visible
'active': @state.active
<div className={classes}>
<ContentComponent messageOverride={messageOverride}/>
</div>
_onChange: ->
@setState
layoutMode: WorkspaceStore.layoutMode()
syncing: NylasSyncStatusStore.busy()
module.exports = EmptyState