fix(template): Rewrite in ES6, add missing windowTypes

This commit is contained in:
Ben Gotow 2016-03-21 18:25:43 -07:00
parent fce1673aac
commit 9e3dbd3873
11 changed files with 213 additions and 184 deletions

View file

@ -232,7 +232,10 @@ PackagesStore = Reflux.createStore
type: 'git'
url: ''
engines:
nylas: ">=#{NylasEnv.getVersion()}"
nylas: ">=#{NylasEnv.getVersion().split('-')[0]}"
windowTypes:
default: true
composer: true
description: "Enter a description of your package!"
dependencies: {}
license: "MIT"

View file

@ -1,30 +0,0 @@
{ComponentRegistry} = require 'nylas-exports'
MyComposerButton = require './my-composer-button'
MyMessageSidebar = require './my-message-sidebar'
module.exports =
# Activate is called when the package is loaded. If your package previously
# saved state using `serialize` it is provided.
#
activate: (@state) ->
ComponentRegistry.register MyComposerButton,
role: 'Composer:ActionButton'
ComponentRegistry.register MyMessageSidebar,
role: 'MessageListSidebar:ContactCard'
# Serialize is called when your package is about to be unmounted.
# You can return a state object that will be passed back to your package
# when it is re-activated.
#
serialize: ->
# This **optional** method is called when the window is shutting down,
# or when your package is being updated or disabled. If your package is
# watching any files, holding external resources, providing commands or
# subscribing to events, release them here.
#
deactivate: ->
ComponentRegistry.unregister(MyComposerButton)
ComponentRegistry.unregister(MyMessageSidebar)

View file

@ -0,0 +1,33 @@
import {ComponentRegistry} from 'nylas-exports';
import MyComposerButton from './my-composer-button';
import MyMessageSidebar from './my-message-sidebar';
// Activate is called when the package is loaded. If your package previously
// saved state using `serialize` it is provided.
//
export function activate() {
ComponentRegistry.register(MyComposerButton, {
role: 'Composer:ActionButton',
});
ComponentRegistry.register(MyMessageSidebar, {
role: 'MessageListSidebar:ContactCard',
});
}
// Serialize is called when your package is about to be unmounted.
// You can return a state object that will be passed back to your package
// when it is re-activated.
//
export function serialize() {
}
// This **optional** method is called when the window is shutting down,
// or when your package is being updated or disabled. If your package is
// watching any files, holding external resources, providing commands or
// subscribing to events, release them here.
//
export function deactivate() {
ComponentRegistry.unregister(MyComposerButton);
ComponentRegistry.unregister(MyMessageSidebar);
}

View file

@ -1,43 +0,0 @@
{Utils, DraftStore, React} = require 'nylas-exports'
{RetinaImg} = require 'nylas-component-kit'
class MyComposerButton extends React.Component
# Note: You should assign a new displayName to avoid naming
# conflicts when injecting your item
@displayName: 'MyComposerButton'
# When you register as a composer button, you receive a
# reference to the draft, and you can look it up to perform
# actions and retrieve data.
@propTypes:
draftClientId: React.PropTypes.string.isRequired
render: =>
<div className="my-package">
<button className="btn btn-toolbar" onClick={ => @_onClick()} ref="button">
Hello World
</button>
</div>
_onClick: =>
# To retrieve information about the draft, we fetch the current editing
# session from the draft store. We can access attributes of the draft
# and add changes to the session which will be appear immediately.
DraftStore.sessionForClientId(@props.draftClientId).then (session) =>
newSubject = "#{session.draft().subject} - It Worked!"
dialog = @_getDialog()
dialog.showMessageBox
title: 'Here we go...'
detail: "Adjusting the subject line To `#{newSubject}`"
buttons: ['OK']
type: 'info'
session.changes.add({subject: newSubject})
_getDialog: =>
require('remote').require('dialog')
module.exports = MyComposerButton

View file

@ -0,0 +1,48 @@
import {DraftStore, React} from 'nylas-exports';
export default class MyComposerButton extends React.Component {
// Note: You should assign a new displayName to avoid naming
// conflicts when injecting your item
static displayName = 'MyComposerButton';
// When you register as a composer button, you receive a
// reference to the draft, and you can look it up to perform
// actions and retrieve data.
static propTypes = {
draftClientId: React.PropTypes.string.isRequired,
};
_onClick = () => {
// To retrieve information about the draft, we fetch the current editing
// session from the draft store. We can access attributes of the draft
// and add changes to the session which will be appear immediately.
DraftStore.sessionForClientId(this.props.draftClientId).then((session) => {
const newSubject = `${session.draft().subject} - It Worked!`;
const dialog = this._getDialog();
dialog.showMessageBox({
title: 'Here we go...',
detail: "Adjusting the subject line To `#{newSubject}`",
buttons: ['OK'],
type: 'info',
});
session.changes.add({subject: newSubject});
});
}
_getDialog() {
return require('remote').require('dialog');
}
render() {
return (
<div className="my-package">
<button className="btn btn-toolbar" onClick={() => this._onClick()} ref="button">
Hello World
</button>
</div>
);
}
}

View file

@ -1,66 +0,0 @@
{Utils,
React,
FocusedContactsStore} = require 'nylas-exports'
{RetinaImg} = require 'nylas-component-kit'
class MyMessageSidebar extends React.Component
@displayName: 'MyMessageSidebar'
# Providing container styles tells the app how to constrain
# the column your component is being rendered in. The min and
# max size of the column are chosen automatically based on
# these values.
@containerStyles:
order: 1
flexShrink: 0
# This sidebar component listens to the FocusedContactStore,
# which gives us access to the Contact object of the currently
# selected person in the conversation. If you wanted to take
# the contact and fetch your own data, you'd want to create
# your own store, so the flow of data would be:
#
# FocusedContactStore => Your Store => Your Component
#
constructor: (@props) ->
@state = @_getStateFromStores()
componentDidMount: =>
@unsubscribe = FocusedContactsStore.listen(@_onChange)
componentWillUnmount: =>
@unsubscribe()
render: =>
if @state.contact
content = @_renderContent()
else
content = @_renderPlaceholder()
<div className="my-message-sidebar">
{content}
</div>
_renderContent: =>
# Want to include images or other static assets in your components?
# Reference them using the nylas:// URL scheme:
#
# <RetinaImg
# url="nylas://<<package.name>>/assets/checkmark_template@2x.png"
# mode={RetinaImg.Mode.ContentIsMask}/>
#
<div className="header">
<h1>{@state.contact.displayName()} is the focused contact.</h1>
</div>
_renderPlaceholder: =>
<div> No Data Available </div>
_onChange: =>
@setState(@_getStateFromStores())
_getStateFromStores: =>
contact: FocusedContactsStore.focusedContact()
module.exports = MyMessageSidebar

View file

@ -0,0 +1,78 @@
import {
React,
FocusedContactsStore,
} from 'nylas-exports';
export default class MyMessageSidebar extends React.Component {
static displayName = 'MyMessageSidebar';
// This sidebar component listens to the FocusedContactStore,
// which gives us access to the Contact object of the currently
// selected person in the conversation. If you wanted to take
// the contact and fetch your own data, you'd want to create
// your own store, so the flow of data would be:
// FocusedContactStore => Your Store => Your Component
constructor(props) {
super(props);
this.state = this._getStateFromStores();
}
componentDidMount() {
this.unsubscribe = FocusedContactsStore.listen(this._onChange);
}
componentWillUnmount() {
this.unsubscribe();
}
_onChange = () => {
this.setState(this._getStateFromStores());
}
_getStateFromStores = () => {
return {
contact: FocusedContactsStore.focusedContact(),
};
}
_renderContent() {
// Want to include images or other static assets in your components?
// Reference them using the nylas:// URL scheme:
//
// <RetinaImg
// url="nylas://<<package.name>>/assets/checkmark_templatethis.2x.png"
// mode={RetinaImg.Mode.ContentIsMask}/>
//
return (
<div className="header">
<h1>{this.state.contact.displayName()} is the focused contact.</h1>
</div>
);
}
_renderPlaceholder() {
return (
<div> No Data Available </div>
);
}
render() {
const content = (this.state.contact) ? this._renderContent() : this._renderPlaceholder();
return (
<div className="my-message-sidebar">
{content}
</div>
);
}
}
// Providing container styles tells the app how to constrain
// the column your component is being rendered in. The min and
// max size of the column are chosen automatically based on
// these values.
MyMessageSidebar.containerStyles = {
order: 1,
flexShrink: 0,
};

View file

@ -1,19 +0,0 @@
{ComponentRegistry} = require 'nylas-exports'
{activate, deactivate} = require '../lib/main'
MyMessageSidebar = require '../lib/my-message-sidebar'
MyComposerButton = require '../lib/my-composer-button'
describe "activate", ->
it "should register the composer button and sidebar", ->
spyOn(ComponentRegistry, 'register')
activate()
expect(ComponentRegistry.register).toHaveBeenCalledWith(MyComposerButton, {role: 'Composer:ActionButton'})
expect(ComponentRegistry.register).toHaveBeenCalledWith(MyMessageSidebar, {role: 'MessageListSidebar:ContactCard'})
describe "deactivate", ->
it "should unregister the composer button and sidebar", ->
spyOn(ComponentRegistry, 'unregister')
deactivate()
expect(ComponentRegistry.unregister).toHaveBeenCalledWith(MyComposerButton)
expect(ComponentRegistry.unregister).toHaveBeenCalledWith(MyMessageSidebar)

View file

@ -0,0 +1,23 @@
import {ComponentRegistry} from 'nylas-exports';
import {activate, deactivate} from '../lib/main';
import MyMessageSidebar from '../lib/my-message-sidebar';
import MyComposerButton from '../lib/my-composer-button';
describe("activate", () => {
it("should register the composer button and sidebar", () => {
spyOn(ComponentRegistry, 'register');
activate();
expect(ComponentRegistry.register).toHaveBeenCalledWith(MyComposerButton, {role: 'Composer:ActionButton'});
expect(ComponentRegistry.register).toHaveBeenCalledWith(MyMessageSidebar, {role: 'MessageListSidebar:ContactCard'});
});
});
describe("deactivate", () => {
it("should unregister the composer button and sidebar", () => {
spyOn(ComponentRegistry, 'unregister');
deactivate();
expect(ComponentRegistry.unregister).toHaveBeenCalledWith(MyComposerButton);
expect(ComponentRegistry.unregister).toHaveBeenCalledWith(MyMessageSidebar);
});
});

View file

@ -1,25 +0,0 @@
{React} = require 'nylas-exports'
ReactTestUtils = React.addons.TestUtils
MyComposerButton = require '../lib/my-composer-button'
dialogStub =
showMessageBox: jasmine.createSpy('showMessageBox')
describe "MyComposerButton", ->
beforeEach ->
@component = ReactTestUtils.renderIntoDocument(
<MyComposerButton draftClientId="test" />
)
it "should render into the page", ->
expect(@component).toBeDefined()
it "should have a displayName", ->
expect(MyComposerButton.displayName).toBe('MyComposerButton')
it "should show a dialog box when clicked", ->
spyOn(@component, '_onClick')
buttonNode = React.findDOMNode(@component.refs.button)
ReactTestUtils.Simulate.click(buttonNode)
expect(@component._onClick).toHaveBeenCalled()

View file

@ -0,0 +1,27 @@
import {React} from 'nylas-exports';
const ReactTestUtils = React.addons.TestUtils
import MyComposerButton from '../lib/my-composer-button';
describe("MyComposerButton", () => {
beforeEach(() => {
this.component = ReactTestUtils.renderIntoDocument(
<MyComposerButton draftClientId="test" />
);
});
it("should render into the page", () => {
expect(this.component).toBeDefined();
});
it("should have a displayName", () => {
expect(MyComposerButton.displayName).toBe('MyComposerButton');
});
it("should show a dialog box when clicked", () => {
spyOn(this.component, '_onClick');
const buttonNode = React.findDOMNode(this.component.refs.button);
ReactTestUtils.Simulate.click(buttonNode);
expect(this.component._onClick).toHaveBeenCalled();
});
});