diff --git a/internal_packages/composer-markdown/README.md b/internal_packages/composer-markdown/README.md new file mode 100644 index 000000000..faab9413a --- /dev/null +++ b/internal_packages/composer-markdown/README.md @@ -0,0 +1,26 @@ + +# N1 Markdown Composer + +A plugin for N1 that allows you to compose emails using markdown. + +![Markdown Screenshot Editor](/assets/markdown_screenshot_edit.png?raw=true "Markdown Composer Editor") +![Markdown Screenshot Preview](/assets/markdown_screenshot_preview.png?raw=true "Markdown Composer Preview") + +## Install this plugin: + +1. Download and run N1 + +2. Clone this repository (Make sure you have `git` installed and available in + your system path) + +3. From the menu, select `Developer > Install a Package Manually...` + From the dialog, choose the directory of this plugin to install it! + + > When you install packages, they're moved to `~/.nylas/packages`, + > and N1 runs `apm install` on the command line to fetch dependencies + > listed in the package's `package.json` + + +## Usage + +Just write emails using markdown. diff --git a/internal_packages/composer-markdown/assets/markdown_screenshot_edit.png b/internal_packages/composer-markdown/assets/markdown_screenshot_edit.png new file mode 100644 index 000000000..2120bdc2d Binary files /dev/null and b/internal_packages/composer-markdown/assets/markdown_screenshot_edit.png differ diff --git a/internal_packages/composer-markdown/assets/markdown_screenshot_preview.png b/internal_packages/composer-markdown/assets/markdown_screenshot_preview.png new file mode 100644 index 000000000..c8361d20f Binary files /dev/null and b/internal_packages/composer-markdown/assets/markdown_screenshot_preview.png differ diff --git a/internal_packages/composer-markdown/icon.png b/internal_packages/composer-markdown/icon.png new file mode 100644 index 000000000..2683b3b42 Binary files /dev/null and b/internal_packages/composer-markdown/icon.png differ diff --git a/internal_packages/composer-markdown/lib/main.cjsx b/internal_packages/composer-markdown/lib/main.cjsx new file mode 100644 index 000000000..fe1bbf713 --- /dev/null +++ b/internal_packages/composer-markdown/lib/main.cjsx @@ -0,0 +1,21 @@ +# Markdown Editor +# Last Revised: April 23, 2015 by Ben Gotow +# +# Markdown editor is a simple React component that allows you to type your +# emails in markdown and see the live preview of your email in html +# +{ExtensionRegistry, ComponentRegistry} = require 'nylas-exports' +MarkdownEditor = require './markdown-editor' +MarkdownComposerExtension = require './markdown-composer-extension' + +module.exports = + activate: -> + ComponentRegistry.register MarkdownEditor, + role: 'Composer:Editor' + ExtensionRegistry.Composer.register(MarkdownComposerExtension) + + serialize: -> + + deactivate: -> + ComponentRegistry.unregister(MarkdownEditor) + ExtensionRegistry.Composer.unregister(MarkdownComposerExtension) diff --git a/internal_packages/composer-markdown/lib/markdown-composer-extension.coffee b/internal_packages/composer-markdown/lib/markdown-composer-extension.coffee new file mode 100644 index 000000000..f08f00a4a --- /dev/null +++ b/internal_packages/composer-markdown/lib/markdown-composer-extension.coffee @@ -0,0 +1,21 @@ +marked = require 'marked' +Utils = require './utils' +{ComposerExtension} = require 'nylas-exports' + + +rawBodies = {} + +class MarkdownComposerExtension extends ComposerExtension + + @applyTransformsToDraft: ({draft}) -> + nextDraft = draft.clone() + rawBodies[draft.clientId] = nextDraft.body + nextDraft.body = marked(Utils.getTextFromHtml(draft.body)) + return nextDraft + + @unapplyTransformsToDraft: ({draft}) -> + nextDraft = draft.clone() + nextDraft.body = rawBodies[nextDraft.clientId] ? nextDraft.body + return nextDraft + +module.exports = MarkdownComposerExtension diff --git a/internal_packages/composer-markdown/lib/markdown-editor.cjsx b/internal_packages/composer-markdown/lib/markdown-editor.cjsx new file mode 100644 index 000000000..05ef12e32 --- /dev/null +++ b/internal_packages/composer-markdown/lib/markdown-editor.cjsx @@ -0,0 +1,72 @@ +Utils = require './utils' +SimpleMDE = require 'simplemde' +nylas = require 'nylas-exports' +React = nylas.React +ReactDOM = nylas.ReactDOM + +# Keep a file-scope variable containing the contents of the markdown stylesheet. +# This will be embedded in the markdown preview iFrame, as well as the email body. +# The stylesheet is loaded when a preview component is first mounted. +markdownStylesheet = null + +class MarkdownEditor extends React.Component + @displayName: 'MarkdownEditor' + + @propTypes: + body: React.PropTypes.string.isRequired, + onBodyChanged: React.PropTypes.func.isRequired, + + componentDidMount: => + textarea = ReactDOM.findDOMNode(@refs.textarea) + @mde = new SimpleMDE( + element: textarea, + hideIcons: ['fullscreen', 'side-by-side'] + showIcons: ['code', 'table'] + ) + @mde.codemirror.on "change", @_onBodyChanged + @mde.value(Utils.getTextFromHtml(@props.body)) + + componentWillReceiveProps: (newProps) => + currentText = Utils.getTextFromHtml(@props.body) + if @props.body isnt newProps.body and currentText.length is 0 + @mde.value(Utils.getTextFromHtml(newProps.body)) + @mde.codemirror.execCommand('goDocEnd') + + focus: => + @mde.codemirror.focus() + @mde.codemirror.execCommand('goDocEnd') + + focusAbsoluteEnd: => + @focus() + + getCurrentSelection: -> + + getPreviousSelection: -> + + setSelection: -> + + _onDOMMutated: -> + + _onBodyChanged: => + setImmediate => + @props.onBodyChanged(target: {value: @mde.value()}) + + render: -> + # TODO sorry + # Add style tag to disable incompatible plugins +
+ +