mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-09-04 03:34:28 +08:00
Docs styling improvements
This commit is contained in:
parent
8b7964a140
commit
47ab0cf302
21 changed files with 365 additions and 1124 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -21,7 +21,7 @@
|
|||
<li><a href="http://slack-invite.nylas.com/" target="_blank">Support</a></li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li class="btn btn-emphasis"><a href="https://invite.nylas.com/download">Download</a></li>
|
||||
<li><a class="btn btn-emphasis" href="https://invite.nylas.com/download">Download</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<div class="heading">{{include.section.name}}</div>
|
||||
<ul>
|
||||
{% for item in include.section.items %}
|
||||
{% if item.items %}
|
||||
{% include sidebar_section.html section=item %}
|
||||
{% else %}
|
||||
<li class="{% if page.url contains item.link %}active{% endif %}"><a href="{{item.link}}" {% if item.external %}target="_blank"{% endif %}>{{item.name}}</a></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<div class="section">
|
||||
<a class="heading" href="{{include.section.link}}" {% if include.section.external %}target="_blank"{% endif %}>{{include.section.name}}</a>
|
||||
<ul>
|
||||
{% for item in include.section.items %}
|
||||
{% if item.items %}
|
||||
{% include sidebar_section.html section=item %}
|
||||
{% else %}
|
||||
<li class="{% if page.url contains item.link %}active{% endif %}"><a href="{{item.link}}" {% if item.external %}target="_blank"{% endif %}>{{item.name}}</a></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
{% include header.html %}
|
||||
|
||||
<div class="container container-docs" style="padding-top:80px;">
|
||||
<h2 id="doc-title">{{ page.title }}</h2>
|
||||
|
||||
<div id="sidebar">
|
||||
{% include sidebar.html %}
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
.container-docs {
|
||||
color: #737373;
|
||||
color: #545454;
|
||||
font-size:1em;
|
||||
|
||||
h1,
|
||||
h2,
|
||||
|
@ -17,6 +18,8 @@
|
|||
}
|
||||
p {
|
||||
margin-bottom: 12px;
|
||||
font-size:1em;
|
||||
font-weight: 300;
|
||||
}
|
||||
h1,
|
||||
h2,
|
||||
|
@ -26,6 +29,9 @@
|
|||
h6 {
|
||||
color: #404040;
|
||||
line-height: 36px;
|
||||
font-weight: 500;
|
||||
opacity: 1;
|
||||
margin-bottom:15px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 40px;
|
||||
|
@ -63,6 +69,13 @@
|
|||
margin-top:0;
|
||||
}
|
||||
|
||||
.markdown-from-sourecode {
|
||||
h4, h3, h2, h1 {
|
||||
font-size: 18px;
|
||||
margin-top:20px;
|
||||
margin-bottom:5px;
|
||||
}
|
||||
}
|
||||
blockquote {
|
||||
padding: 13px 13px 21px 15px;
|
||||
margin-bottom: 18px;
|
||||
|
@ -78,7 +91,7 @@
|
|||
font-style: italic;
|
||||
}
|
||||
blockquote code {
|
||||
background-color:white;
|
||||
background-color:#f2f2f2;
|
||||
}
|
||||
img {
|
||||
max-width:100%;
|
||||
|
@ -87,8 +100,8 @@
|
|||
font-family: Monaco, Andale Mono, Courier New, monospace;
|
||||
}
|
||||
code {
|
||||
color: rgba(0, 0, 0, 0.75);
|
||||
background-color: #EAF7F6;
|
||||
color: rgba(0,0,0,0.76);
|
||||
background-color: #f2f2f2;
|
||||
padding: 1px 3px;
|
||||
font-size: 14px;
|
||||
-webkit-border-radius: 3px;
|
||||
|
@ -105,7 +118,7 @@
|
|||
}
|
||||
pre code {
|
||||
font-size: 13px;
|
||||
background-color: white;
|
||||
background-color: #f2f2f2;
|
||||
padding: 0;
|
||||
display: block;
|
||||
padding: 14px;
|
||||
|
@ -118,6 +131,66 @@
|
|||
* {
|
||||
-webkit-print-color-adjust: exact;
|
||||
}
|
||||
a {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
float:left;
|
||||
position:static;
|
||||
width:250px;
|
||||
|
||||
.section {
|
||||
padding-bottom:15px;
|
||||
|
||||
&.collapsed {
|
||||
ul {
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
a.heading {
|
||||
color:#404040;
|
||||
line-height:28px;
|
||||
font-size:16px;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin:0;
|
||||
padding-left:15px;
|
||||
height: 100%;
|
||||
transition: all 200ms ease-out;
|
||||
|
||||
li {
|
||||
list-style-type:none;
|
||||
a {
|
||||
color:#404040;
|
||||
font-size:14px;
|
||||
line-height:1.8em;
|
||||
}
|
||||
}
|
||||
li.active a {
|
||||
color:black;
|
||||
font-size:14px;
|
||||
font-weight: bold;
|
||||
line-height:1.8em;
|
||||
}
|
||||
.heading {
|
||||
line-height:22px;
|
||||
font-size:14px;
|
||||
padding-top:6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#doc-title {
|
||||
margin-top:30px;
|
||||
margin-bottom:30px;
|
||||
}
|
||||
|
||||
.link {
|
||||
width:18px;
|
||||
|
@ -125,7 +198,7 @@
|
|||
display:inline-block;
|
||||
vertical-align:sub;
|
||||
opacity:0.4;
|
||||
background:url(/images/link.png) top left;
|
||||
background:url(../docs/images/link.png) top left;
|
||||
background-size:cover;
|
||||
}
|
||||
|
||||
|
|
|
@ -107,43 +107,6 @@ a img {
|
|||
margin-left:290px;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
float:left;
|
||||
position:static;
|
||||
width:250px;
|
||||
}
|
||||
|
||||
#sidebar .heading {
|
||||
color:#404040;
|
||||
line-height:28px;
|
||||
font-size:16px;
|
||||
font-weight:bold;
|
||||
}
|
||||
#sidebar ul .heading {
|
||||
line-height:22px;
|
||||
font-size:14px;
|
||||
padding-top:6px;
|
||||
}
|
||||
|
||||
#sidebar ul {
|
||||
margin-top:0;
|
||||
padding-left:15px;
|
||||
}
|
||||
#sidebar ul li {
|
||||
list-style-type:none;
|
||||
}
|
||||
#sidebar ul li a {
|
||||
color:#404040;
|
||||
font-size:14px;
|
||||
line-height:1.8em;
|
||||
}
|
||||
#sidebar ul li.active a {
|
||||
color:black;
|
||||
font-size:14px;
|
||||
font-weight: bold;
|
||||
line-height:1.8em;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-weight:200;
|
||||
font-size:40px;
|
||||
|
@ -340,9 +303,10 @@ p {
|
|||
li {
|
||||
list-style-type: none;
|
||||
display: inline-block;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
color: rgba(0,0,0,0.7);
|
||||
a {
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
li:hover {
|
||||
color: rgba(0,0,0,1);
|
||||
|
@ -354,7 +318,8 @@ p {
|
|||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
.btn,
|
||||
.nav li .btn {
|
||||
-webkit-user-select:none;
|
||||
padding: 0.33em 1em;
|
||||
border-radius: 4px;
|
||||
|
@ -379,7 +344,8 @@ p {
|
|||
font-size: 20px;
|
||||
}
|
||||
|
||||
.btn.btn-emphasis {
|
||||
.btn.btn-emphasis,
|
||||
.nav li .btn.btn-emphasis {
|
||||
position: relative;
|
||||
color: white;
|
||||
background: linear-gradient(to bottom, #6bb1f9 0%, #0a80ff 100%);
|
||||
|
|
|
@ -1,93 +1,218 @@
|
|||
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
|
||||
|
||||
/* Tomorrow Comment */
|
||||
.hljs-comment {
|
||||
color: #8e908c;
|
||||
}
|
||||
|
||||
/* Tomorrow Red */
|
||||
.hljs-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-regexp,
|
||||
.ruby .hljs-constant,
|
||||
.xml .hljs-tag .hljs-title,
|
||||
.xml .hljs-pi,
|
||||
.xml .hljs-doctype,
|
||||
.html .hljs-doctype,
|
||||
.css .hljs-id,
|
||||
.css .hljs-class,
|
||||
.css .hljs-pseudo {
|
||||
color: #c82829;
|
||||
}
|
||||
|
||||
/* Tomorrow Orange */
|
||||
.hljs-number,
|
||||
.hljs-preprocessor,
|
||||
.hljs-pragma,
|
||||
.hljs-built_in,
|
||||
.hljs-literal,
|
||||
.hljs-params,
|
||||
.hljs-constant {
|
||||
color: #f5871f;
|
||||
}
|
||||
|
||||
/* Tomorrow Yellow */
|
||||
.ruby .hljs-class .hljs-title,
|
||||
.css .hljs-rule .hljs-attribute {
|
||||
color: #eab700;
|
||||
}
|
||||
|
||||
/* Tomorrow Green */
|
||||
.hljs-string,
|
||||
.hljs-value,
|
||||
.hljs-inheritance,
|
||||
.hljs-header,
|
||||
.hljs-name,
|
||||
.ruby .hljs-symbol,
|
||||
.xml .hljs-cdata {
|
||||
color: #718c00;
|
||||
}
|
||||
|
||||
/* Tomorrow Aqua */
|
||||
.hljs-title,
|
||||
.css .hljs-hexcolor {
|
||||
color: #3e999f;
|
||||
}
|
||||
|
||||
/* Tomorrow Blue */
|
||||
.hljs-function,
|
||||
.python .hljs-decorator,
|
||||
.python .hljs-title,
|
||||
.ruby .hljs-function .hljs-title,
|
||||
.ruby .hljs-title .hljs-keyword,
|
||||
.perl .hljs-sub,
|
||||
.javascript .hljs-title,
|
||||
.coffeescript .hljs-title {
|
||||
color: #4271ae;
|
||||
}
|
||||
|
||||
/* Tomorrow Purple */
|
||||
.hljs-keyword,
|
||||
.javascript .hljs-function {
|
||||
color: #8959a8;
|
||||
}
|
||||
/**
|
||||
* GitHub Gist Theme
|
||||
* Author : Louis Barranqueiro - https://github.com/LouisBarranqueiro
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: white;
|
||||
color: #4d4d4c;
|
||||
padding: 0.5em;
|
||||
color: #333333;
|
||||
overflow-x: auto;
|
||||
-webkit-text-size-adjust: none;
|
||||
}
|
||||
|
||||
.coffeescript .javascript,
|
||||
.javascript .xml,
|
||||
.tex .hljs-formula,
|
||||
.xml .javascript,
|
||||
.xml .vbscript,
|
||||
.xml .css,
|
||||
.xml .hljs-cdata {
|
||||
opacity: 0.5;
|
||||
.hljs-comment,
|
||||
.bash .hljs-shebang,
|
||||
.java .hljs-javadoc,
|
||||
.javascript .hljs-javadoc,
|
||||
.rust .hljs-preprocessor {
|
||||
color: #969896;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.apache .hljs-sqbracket,
|
||||
.coffeescript .hljs-subst,
|
||||
.coffeescript .hljs-regexp,
|
||||
.cpp .hljs-preprocessor,
|
||||
.c .hljs-preprocessor,
|
||||
.javascript .hljs-regexp,
|
||||
.json .hljs-attribute,
|
||||
.makefile .hljs-variable,
|
||||
.markdown .hljs-value,
|
||||
.markdown .hljs-link_label,
|
||||
.markdown .hljs-strong,
|
||||
.markdown .hljs-emphasis,
|
||||
.markdown .hljs-blockquote,
|
||||
.nginx .hljs-regexp,
|
||||
.nginx .hljs-number,
|
||||
.objectivec .hljs-preprocessor .hljs-title,
|
||||
.perl .hljs-regexp,
|
||||
.php .hljs-regexp,
|
||||
.xml .hljs-value,
|
||||
.less .hljs-built_in,
|
||||
.scss .hljs-built_in {
|
||||
color: #df5000;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.css .hljs-at_rule,
|
||||
.css .hljs-important,
|
||||
.http .hljs-request,
|
||||
.ini .hljs-setting,
|
||||
.haskell .hljs-type,
|
||||
.java .hljs-javadoctag,
|
||||
.javascript .hljs-tag,
|
||||
.javascript .hljs-javadoctag,
|
||||
.nginx .hljs-title,
|
||||
.objectivec .hljs-preprocessor,
|
||||
.php .hljs-phpdoc,
|
||||
.sql .hljs-built_in,
|
||||
.less .hljs-tag,
|
||||
.less .hljs-at_rule,
|
||||
.scss .hljs-tag,
|
||||
.scss .hljs-at_rule,
|
||||
.scss .hljs-important,
|
||||
.stylus .hljs-at_rule,
|
||||
.go .hljs-typename,
|
||||
.swift .hljs-preprocessor {
|
||||
color: #a71d5d;
|
||||
}
|
||||
|
||||
.apache .hljs-common,
|
||||
.apache .hljs-cbracket,
|
||||
.apache .hljs-keyword,
|
||||
.bash .hljs-literal,
|
||||
.bash .hljs-built_in,
|
||||
.coffeescript .hljs-literal,
|
||||
.coffeescript .hljs-built_in,
|
||||
.coffeescript .hljs-number,
|
||||
.cpp .hljs-number,
|
||||
.cpp .hljs-built_in,
|
||||
.c .hljs-number,
|
||||
.c .hljs-built_in,
|
||||
.cs .hljs-number,
|
||||
.cs .hljs-built_in,
|
||||
.css .hljs-attribute,
|
||||
.css .hljs-hexcolor,
|
||||
.css .hljs-number,
|
||||
.css .hljs-function,
|
||||
.haskell .hljs-number,
|
||||
.http .hljs-literal,
|
||||
.http .hljs-attribute,
|
||||
.java .hljs-number,
|
||||
.javascript .hljs-built_in,
|
||||
.javascript .hljs-literal,
|
||||
.javascript .hljs-number,
|
||||
.json .hljs-number,
|
||||
.makefile .hljs-keyword,
|
||||
.markdown .hljs-link_reference,
|
||||
.nginx .hljs-built_in,
|
||||
.objectivec .hljs-literal,
|
||||
.objectivec .hljs-number,
|
||||
.objectivec .hljs-built_in,
|
||||
.php .hljs-literal,
|
||||
.php .hljs-number,
|
||||
.python .hljs-number,
|
||||
.ruby .hljs-prompt,
|
||||
.ruby .hljs-constant,
|
||||
.ruby .hljs-number,
|
||||
.ruby .hljs-subst .hljs-keyword,
|
||||
.ruby .hljs-symbol,
|
||||
.rust .hljs-number,
|
||||
.sql .hljs-number,
|
||||
.puppet .hljs-function,
|
||||
.less .hljs-number,
|
||||
.less .hljs-hexcolor,
|
||||
.less .hljs-function,
|
||||
.less .hljs-attribute,
|
||||
.scss .hljs-preprocessor,
|
||||
.scss .hljs-number,
|
||||
.scss .hljs-hexcolor,
|
||||
.scss .hljs-function,
|
||||
.scss .hljs-attribute,
|
||||
.stylus .hljs-number,
|
||||
.stylus .hljs-hexcolor,
|
||||
.stylus .hljs-attribute,
|
||||
.stylus .hljs-params,
|
||||
.go .hljs-built_in,
|
||||
.go .hljs-constant,
|
||||
.swift .hljs-built_in,
|
||||
.swift .hljs-number {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.apache .hljs-tag,
|
||||
.cs .hljs-xmlDocTag,
|
||||
.css .hljs-tag,
|
||||
.xml .hljs-title,
|
||||
.stylus .hljs-tag {
|
||||
color: #63a35c;
|
||||
}
|
||||
|
||||
.bash .hljs-variable,
|
||||
.cs .hljs-preprocessor,
|
||||
.cs .hljs-preprocessor .hljs-keyword,
|
||||
.css .hljs-attr_selector,
|
||||
.css .hljs-value,
|
||||
.ini .hljs-value,
|
||||
.ini .hljs-keyword,
|
||||
.javascript .hljs-tag .hljs-title,
|
||||
.makefile .hljs-constant,
|
||||
.nginx .hljs-variable,
|
||||
.xml .hljs-tag,
|
||||
.scss .hljs-variable {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.bash .hljs-title,
|
||||
.coffeescript .hljs-title,
|
||||
.cpp .hljs-title,
|
||||
.c .hljs-title,
|
||||
.cs .hljs-title,
|
||||
.css .hljs-id,
|
||||
.css .hljs-class,
|
||||
.css .hljs-pseudo,
|
||||
.ini .hljs-title,
|
||||
.haskell .hljs-title,
|
||||
.haskell .hljs-pragma,
|
||||
.java .hljs-title,
|
||||
.javascript .hljs-title,
|
||||
.makefile .hljs-title,
|
||||
.objectivec .hljs-title,
|
||||
.perl .hljs-sub,
|
||||
.php .hljs-title,
|
||||
.python .hljs-decorator,
|
||||
.python .hljs-title,
|
||||
.ruby .hljs-parent,
|
||||
.ruby .hljs-title,
|
||||
.rust .hljs-title,
|
||||
.xml .hljs-attribute,
|
||||
.puppet .hljs-title,
|
||||
.less .hljs-id,
|
||||
.less .hljs-pseudo,
|
||||
.less .hljs-class,
|
||||
.scss .hljs-id,
|
||||
.scss .hljs-pseudo,
|
||||
.scss .hljs-class,
|
||||
.stylus .hljs-class,
|
||||
.stylus .hljs-id,
|
||||
.stylus .hljs-pseudo,
|
||||
.stylus .hljs-title,
|
||||
.swift .hljs-title,
|
||||
.diff .hljs-chunk {
|
||||
color: #795da3;
|
||||
}
|
||||
|
||||
.coffeescript .hljs-reserved,
|
||||
.coffeescript .hljs-attribute {
|
||||
color: #1d3e81;
|
||||
}
|
||||
|
||||
.diff .hljs-chunk {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.diff .hljs-addition {
|
||||
color: #55a532;
|
||||
background-color: #eaffea;
|
||||
}
|
||||
|
||||
.diff .hljs-deletion {
|
||||
color: #bd2c00;
|
||||
background-color: #ffecec;
|
||||
}
|
||||
|
||||
.markdown .hljs-link_url {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
|
|
@ -99,12 +99,12 @@ that is not a Store, you can still use the <code>listen</code> method provided b
|
|||
<p><p>Select the provided sheet in the current window. This action changes
|
||||
the top level sheet.</p>
|
||||
<p><em>Scope: Window</em></p>
|
||||
<pre><code>Actions.<span class="hljs-function"><span class="hljs-title">selectRootSheet</span><span class="hljs-params">(WorkspaceStore.Sheet.Threads)</span></span>
|
||||
<pre><code><span class="hljs-tag">Actions</span><span class="hljs-class">.selectRootSheet</span>(<span class="hljs-tag">WorkspaceStore</span><span class="hljs-class">.Sheet</span><span class="hljs-class">.Threads</span>)
|
||||
</code></pre></p>
|
||||
<h4 id=toggleWorkspaceLocationHidden>toggleWorkspaceLocationHidden <a href="#toggleWorkspaceLocationHidden" class="link"></a></h4>
|
||||
<p><p>Toggle whether a particular column is visible. Call this action
|
||||
with one of the Sheet location constants:</p>
|
||||
<pre><code>Actions.<span class="hljs-function"><span class="hljs-title">toggleWorkspaceLocationHidden</span><span class="hljs-params">(WorkspaceStore.Location.MessageListSidebar)</span></span>
|
||||
<pre><code><span class="hljs-tag">Actions</span><span class="hljs-class">.toggleWorkspaceLocationHidden</span>(<span class="hljs-tag">WorkspaceStore</span><span class="hljs-class">.Location</span><span class="hljs-class">.MessageListSidebar</span>)
|
||||
</code></pre></p>
|
||||
<h4 id=setCursorPosition>setCursorPosition <a href="#setCursorPosition" class="link"></a></h4>
|
||||
<p><p>Focus the keyboard on an item in a collection. This action moves the
|
||||
|
@ -237,9 +237,9 @@ that is not a Store, you can still use the <code>listen</code> method provided b
|
|||
<h4 id=removeFile>removeFile <a href="#removeFile" class="link"></a></h4>
|
||||
<p><p>Remove a file from a draft.</p>
|
||||
<p><em>Scope: Window</em></p>
|
||||
<pre><code>Actions<span class="hljs-class">.removeFile</span>
|
||||
file: fileObject
|
||||
messageClientId: draftClientId
|
||||
<pre><code><span class="hljs-tag">Actions</span><span class="hljs-class">.removeFile</span>
|
||||
<span class="hljs-rule"><span class="hljs-attribute">file</span>:<span class="hljs-value"> fileObject
|
||||
messageClientId: draftClientId</span></span>
|
||||
</code></pre></p>
|
||||
<h4 id=popSheet>popSheet <a href="#popSheet" class="link"></a></h4>
|
||||
<p><p>Pop the current sheet off the Sheet stack maintained by the <a href='workspacestore.html'>WorkspaceStore</a>.
|
||||
|
|
|
@ -60,12 +60,12 @@ more info.</p>
|
|||
default, the type it should be, etc. A simple example:</p>
|
||||
<pre><code class="lang-coffee"><span class="hljs-comment"># We want to provide an `enableThing`, and a `thingVolume`</span>
|
||||
config:
|
||||
enableThing:
|
||||
<span class="hljs-built_in">enable</span>Thing:
|
||||
<span class="hljs-built_in">type</span>: <span class="hljs-string">'boolean'</span>
|
||||
<span class="hljs-keyword">default</span>: <span class="hljs-keyword">false</span>
|
||||
default: <span class="hljs-literal">false</span>
|
||||
thingVolume:
|
||||
<span class="hljs-built_in">type</span>: <span class="hljs-string">'integer'</span>
|
||||
<span class="hljs-keyword">default</span>: <span class="hljs-number">5</span>
|
||||
default: <span class="hljs-number">5</span>
|
||||
minimum: <span class="hljs-number">1</span>
|
||||
maximum: <span class="hljs-number">11</span>
|
||||
</code></pre>
|
||||
|
@ -172,11 +172,11 @@ valid CSS color format such as <code>#abc</code>, <code>#abcdef</code>, <code>wh
|
|||
<p>All types support an <code>enum</code> key. The enum key lets you specify all values
|
||||
that the config setting can possibly be. <code>enum</code> <em>must</em> be an array of values
|
||||
of your specified type. Schema:</p>
|
||||
<pre><code class="lang-coffee"><span class="hljs-attribute">config</span>:
|
||||
<span class="hljs-attribute">someSetting</span>:
|
||||
<span class="hljs-attribute">type</span>: <span class="hljs-string">'integer'</span>
|
||||
<span class="hljs-attribute">default</span>: <span class="hljs-number">4</span>
|
||||
<span class="hljs-attribute">enum</span>: [<span class="hljs-number">2</span>, <span class="hljs-number">4</span>, <span class="hljs-number">6</span>, <span class="hljs-number">8</span>]
|
||||
<pre><code class="lang-coffee"><span class="hljs-symbol">config:</span>
|
||||
<span class="hljs-symbol">someSetting:</span>
|
||||
<span class="hljs-symbol">type:</span> <span class="hljs-string">'integer'</span>
|
||||
<span class="hljs-symbol">default:</span> <span class="hljs-number">4</span>
|
||||
<span class="hljs-class"><span class="hljs-keyword">enum</span>: [2, 4, 6, 8]</span>
|
||||
</code></pre>
|
||||
<p>Usage:</p>
|
||||
<pre><code class="lang-coffee">atom.config.<span class="hljs-built_in">set</span>(<span class="hljs-string">'my-package.someSetting'</span>, <span class="hljs-string">'2'</span>)
|
||||
|
|
|
@ -1,432 +0,0 @@
|
|||
---
|
||||
layout: docs
|
||||
title: First Steps
|
||||
---
|
||||
|
||||
|
||||
<div id="sidebar">
|
||||
<div class="heading">Getting Started</div>
|
||||
<ul>
|
||||
<li><a href="FirstSteps.html" >First Steps</a></li>
|
||||
</ul>
|
||||
<div class="heading">Guides</div>
|
||||
<ul>
|
||||
<li><a href="InterfaceConcepts.html" >Interface Concepts</a></li>
|
||||
<li><a href="PackageOverview.html" >Building a Package</a></li>
|
||||
<li><a href="React.html" >Interface Components</a></li>
|
||||
<li><a href="Architecture.html" >Application Architecture</a></li>
|
||||
<li><a href="Debugging.html" >Debugging N1</a></li>
|
||||
<li><a href="Database.html" >Accessing the Database</a></li>
|
||||
<li><a href="DraftStoreExtensions.html" >Extending the Composer</a></li>
|
||||
<li><a href="WritingSpecs.html" >Writing Specs</a></li>
|
||||
<li><a href="FAQ.html" >FAQ</a></li>
|
||||
</ul>
|
||||
<div class="heading">Sample Code</div>
|
||||
<ul>
|
||||
<li><a href="https://github.com/nylas/edgehill-plugins/tree/master/translate" target="_blank">Composer Translation</a></li>
|
||||
<li><a href="https://github.com/nylas/edgehill-plugins/tree/master/sidebar-github-profile" target="_blank">Github Sidebar</a></li>
|
||||
</ul>
|
||||
<div class="heading">API Reference</div>
|
||||
<ul>
|
||||
<div class="heading">General</div>
|
||||
<ul>
|
||||
<li><a href="Actions.html" >Actions</a></li>
|
||||
<li><a href="Atom.html" >Atom</a></li>
|
||||
<li><a href="BufferedNodeProcess.html" >BufferedNodeProcess</a></li>
|
||||
<li><a href="BufferedProcess.html" >BufferedProcess</a></li>
|
||||
<li><a href="ChangeFolderTask.html" >ChangeFolderTask</a></li>
|
||||
<li><a href="ChangeLabelsTask.html" >ChangeLabelsTask</a></li>
|
||||
<li><a href="Config.html" >Config</a></li>
|
||||
<li><a href="DraggableImg.html" >DraggableImg</a></li>
|
||||
<li><a href="FocusTrackingRegion.html" >FocusTrackingRegion</a></li>
|
||||
<li><a href="Switch.html" >Switch</a></li>
|
||||
<li><a href="Task.html" >Task</a></li>
|
||||
<li><a href="TaskQueueStatusStore.html" >TaskQueueStatusStore</a></li>
|
||||
</ul>
|
||||
<div class="heading">Component Kit</div>
|
||||
<ul>
|
||||
<li><a href="EventedIFrame.html" >EventedIFrame</a></li>
|
||||
<li><a href="Flexbox.html" >Flexbox</a></li>
|
||||
<li><a href="InjectedComponent.html" >InjectedComponent</a></li>
|
||||
<li><a href="InjectedComponentSet.html" >InjectedComponentSet</a></li>
|
||||
<li><a href="Menu.html" >Menu</a></li>
|
||||
<li><a href="MenuItem.html" >MenuItem</a></li>
|
||||
<li><a href="MenuNameEmailItem.html" >MenuNameEmailItem</a></li>
|
||||
<li><a href="MultiselectActionBar.html" >MultiselectActionBar</a></li>
|
||||
<li><a href="MultiselectList.html" >MultiselectList</a></li>
|
||||
<li><a href="Popover.html" >Popover</a></li>
|
||||
<li><a href="ResizableRegion.html" >ResizableRegion</a></li>
|
||||
<li><a href="RetinaImg.html" >RetinaImg</a></li>
|
||||
<li><a href="Spinner.html" >Spinner</a></li>
|
||||
<li><a href="TimeoutTransitionGroupChild.html" >TimeoutTransitionGroupChild</a></li>
|
||||
<li><a href="UnsafeComponent.html" >UnsafeComponent</a></li>
|
||||
</ul>
|
||||
<div class="heading">Models</div>
|
||||
<ul>
|
||||
<li><a href="Account.html" >Account</a></li>
|
||||
<li><a href="Calendar.html" >Calendar</a></li>
|
||||
<li><a href="Contact.html" >Contact</a></li>
|
||||
<li><a href="File.html" >File</a></li>
|
||||
<li><a href="Folder.html" >Folder</a></li>
|
||||
<li><a href="Label.html" >Label</a></li>
|
||||
<li><a href="Message.html" >Message</a></li>
|
||||
<li><a href="Model.html" >Model</a></li>
|
||||
<li><a href="Thread.html" >Thread</a></li>
|
||||
</ul>
|
||||
<div class="heading">Stores</div>
|
||||
<ul>
|
||||
<li><a href="AccountStore.html" >AccountStore</a></li>
|
||||
<li><a href="ComponentRegistry.html" >ComponentRegistry</a></li>
|
||||
<li><a href="ContactStore.html" >ContactStore</a></li>
|
||||
<li><a href="EventStore.html" >EventStore</a></li>
|
||||
<li><a href="FocusedContentStore.html" >FocusedContentStore</a></li>
|
||||
<li><a href="MessageStoreExtension.html" >MessageStoreExtension</a></li>
|
||||
<li><a href="TaskQueue.html" >TaskQueue</a></li>
|
||||
<li><a href="WorkspaceStore.html" >WorkspaceStore</a></li>
|
||||
</ul>
|
||||
<div class="heading">Database</div>
|
||||
<ul>
|
||||
<li><a href="Attribute.html" >Attribute</a></li>
|
||||
<li><a href="AttributeBoolean.html" >AttributeBoolean</a></li>
|
||||
<li><a href="AttributeCollection.html" >AttributeCollection</a></li>
|
||||
<li><a href="AttributeDateTime.html" >AttributeDateTime</a></li>
|
||||
<li><a href="AttributeJoinedData.html" >AttributeJoinedData</a></li>
|
||||
<li><a href="AttributeNumber.html" >AttributeNumber</a></li>
|
||||
<li><a href="AttributeObject.html" >AttributeObject</a></li>
|
||||
<li><a href="AttributeServerId.html" >AttributeServerId</a></li>
|
||||
<li><a href="AttributeString.html" >AttributeString</a></li>
|
||||
<li><a href="DatabaseStore.html" >DatabaseStore</a></li>
|
||||
<li><a href="DatabaseView.html" >DatabaseView</a></li>
|
||||
<li><a href="Matcher.html" >Matcher</a></li>
|
||||
<li><a href="ModelQuery.html" >ModelQuery</a></li>
|
||||
<li><a href="SortOrder.html" >SortOrder</a></li>
|
||||
</ul>
|
||||
<div class="heading">Drafts</div>
|
||||
<ul>
|
||||
<li><a href="DraftChangeSet.html" >DraftChangeSet</a></li>
|
||||
<li><a href="DraftStore.html" >DraftStore</a></li>
|
||||
<li><a href="DraftStoreExtension.html" >DraftStoreExtension</a></li>
|
||||
<li><a href="DraftStoreProxy.html" >DraftStoreProxy</a></li>
|
||||
</ul>
|
||||
<div class="heading">Atom</div>
|
||||
<ul>
|
||||
<li><a href="Clipboard.html" >Clipboard</a></li>
|
||||
<li><a href="Color.html" >Color</a></li>
|
||||
<li><a href="CommandRegistry.html" >CommandRegistry</a></li>
|
||||
<li><a href="MenuManager.html" >MenuManager</a></li>
|
||||
<li><a href="PackageManager.html" >PackageManager</a></li>
|
||||
<li><a href="ScopeDescriptor.html" >ScopeDescriptor</a></li>
|
||||
<li><a href="StyleManager.html" >StyleManager</a></li>
|
||||
<li><a href="ThemeManager.html" >ThemeManager</a></li>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="main" class="article">
|
||||
<style>
|
||||
h3 {
|
||||
line-height: 40px;
|
||||
color:#00B883;
|
||||
}
|
||||
h3.padded {
|
||||
padding-top: 80px;
|
||||
padding-bottom: 25px;
|
||||
}
|
||||
h3 .number {
|
||||
width:40px;
|
||||
height:40px;
|
||||
margin-right:20px;
|
||||
border-radius:50%;
|
||||
border:1px solid #00B883;
|
||||
float:left;
|
||||
color:#00B883;
|
||||
text-align: center;
|
||||
}
|
||||
h3.first {
|
||||
padding-top:40px;
|
||||
}
|
||||
h3.second {
|
||||
color: #00A180;
|
||||
}
|
||||
h3.second .number {
|
||||
border:1px solid #00A180;
|
||||
color: #00A180;
|
||||
}
|
||||
h3.third {
|
||||
color: #009899;
|
||||
}
|
||||
h3.third .number {
|
||||
border:1px solid #009899;
|
||||
color: #009899;
|
||||
}
|
||||
h4 {
|
||||
line-height: 26px;
|
||||
font-size: 16px;
|
||||
color:#89C9C8;
|
||||
margin-top: 30px;
|
||||
margin-bottom: 45px;
|
||||
}
|
||||
h4 .letter {
|
||||
width:22px;
|
||||
height:22px;
|
||||
margin-right:15px;
|
||||
font-size: 14px;
|
||||
background-color: #89C9C8;
|
||||
float:left;
|
||||
color:white;
|
||||
text-align: center;
|
||||
}
|
||||
p {
|
||||
font-size:1.1em;
|
||||
line-height: 1.6em;
|
||||
color:rgba(0,0,0,0.5);
|
||||
}
|
||||
blockquote p {
|
||||
font-size: 15px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2>Start building on top of Nylas in minutes:</h2>
|
||||
<p>Packages lie at the heart of N1. The thread list, composer and other core parts of the app are packages bundled with the app, and extending N1 is as simple as creating a new package.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<h3 class="first padded"><div class="number">1</div> Install N1</h3>
|
||||
<p>Download and install Nylas for <span id="platforms"></span>. Open it and sign in to your email account.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<h3 class="second padded"><div class="number">2</div> Start a Package</h3>
|
||||
<p>From the Developer Menu, choose <span class="instruction-literal">Create a Package...</span> and name your new package.</p>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<img src="./images/Step2-Menu@2x.png" width="203" height="194" style="margin-top:88px;"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h3 class="third padded"><div class="number">3</div> See it in Action</h3>
|
||||
<p>The example package just created adds a section to the message sidebar and is already enabled, view a message to see it in action! If you make changes to the source, choose <span class="instruction-literal">View > Refresh</span> to see your changes in N1.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2 class="continue"><a href="getting-started-2">Explore the package</a></h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6" style="padding-right:30px;">
|
||||
<h4><div class="letter">A</div>Source dive</h4>
|
||||
<img src="./images/Illu-ExploreTheSource@2x.png" width="121" height="96" style="margin:auto; margin-bottom:35px; display:block;"/>
|
||||
<p>N1 is built on the modern web - packages are written in CoffeeScript or JavaScript. Packages are a lot like node modules, with their own source, assets, and tests. Check out the packages that power your N1, located in <span class="instruction-literal">~/.nylas/dev/packages</span>!</p>
|
||||
</div>
|
||||
<div class="col-md-6" style="padding-left:30px;">
|
||||
<h4><div class="letter">B</div> Run the specs</h4>
|
||||
<img src="./images/illu-RunTheSpecs@2x.png" width="139" height="96" style="margin:auto; margin-bottom:35px; display:block;"/>
|
||||
<p>In N1, select <span class="instruction-literal">Developer > Run Package Specs...</span> from the menu to run your package's new specs. Nylas and its packages use the Jasmine testing framework.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 class="gsg-header">Step 2: Building your first package</h2>
|
||||
|
||||
<p>If you followed the <a href="getting-started">first part</a> of our Getting Started Guide, you should have a brand new package just waiting to be explored.</p>
|
||||
<p>This sample package simply adds the name of the currently focused contact to the sidebar:</p>
|
||||
<p><img class="gsg-center" src="images/sidebar-example.png"/></p>
|
||||
<p>We're going to build on this to show the sender's <a href="http://gravatar.com">Gravatar</a> image in the sidebar, instead of just their name. You can check out the full code for the package <a href="https://github.com/nylas/edgehill-plugins/tree/master/sidebar-gravatar">in the sample packages repository</a>.</p>
|
||||
<p>Find the package source in <code>~/.nylas/dev/packages</code> and open the contents in your favorite text editor.</p>
|
||||
<blockquote>
|
||||
<p>We use <a href="https://github.com/jsdf/coffee-react">CJSX</a>, a <a href="http://coffeescript.org/">CoffeeScript</a> syntax for <a href="https://facebook.github.io/react/docs/jsx-in-depth.html">JSX</a>, to streamline our package code.
|
||||
For syntax highlighting, we recommend <a href="https://github.com/babel/babel-sublime">Babel</a> for Sublime, or the <a href="https://atom.io/packages/language-cjsx">CJSX Language</a> Atom package.</p>
|
||||
</blockquote>
|
||||
<h3 id="changing-the-data">Changing the data</h3>
|
||||
<p>Let's poke around and change what the sidebar displays.</p>
|
||||
<p>You'll find the code responsible for the sidebar in <code>lib/my-message-sidebar.cjsx</code>. Take a look at the <code>render</code> method -- this generates the content which appears in the sidebar.</p>
|
||||
<p>(How does it get in the sidebar? See <a href="interfaceconcepts">Interface Concepts</a> and look at <code>main.cjsx</code> for clues. We'll dive into this more later in the guide.)</p>
|
||||
<p>We can change the sidebar to display the contact's email address as well. Check out the <a href="reference/contact">Contact attributes</a> and change the <code>_renderContent</code> method to display more information:</p>
|
||||
<pre><code class="lang-coffee">_renderContent: =>
|
||||
<span class="hljs-variable"><div className="header"></span>
|
||||
<span class="hljs-variable"><h1></span>Hi, {@<span class="hljs-keyword">state</span>.contact.name} ({@<span class="hljs-keyword">state</span>.contact.email})!<span class="hljs-variable"></h1></span>
|
||||
<span class="hljs-variable"></div></span>
|
||||
</code></pre>
|
||||
<p>After making changes to the package, reload N1 by going to <code>View > Reload</code>.</p>
|
||||
<h3 id="installing-a-dependency">Installing a dependency</h3>
|
||||
<p>Now we've figured out how to show the contact's email address, we can use that to generate the <a href="http://gravatar.com">Gravatar</a> for the contact. However, as per the <a href="https://en.gravatar.com/site/implement/images/">Gravatar documentation</a>, we need to be able to calculate the MD5 hash for an email address first.</p>
|
||||
<p>Let's install the <code>md5</code> package and save it as a dependency in our <code>package.json</code>:</p>
|
||||
<pre><code class="lang-bash">$ npm <span class="hljs-operator"><span class="hljs-keyword">install</span> <span class="hljs-keyword">md5</span> <span class="hljs-comment">--save</span></span>
|
||||
</code></pre>
|
||||
<p>Installing other dependencies works the same way.</p>
|
||||
<p>Now, add the <code>md5</code> requirement in <code>my-message-sidebar.cjsx</code> and update the <code>_renderContent</code> method to show the md5 hash:</p>
|
||||
<pre><code class="lang-coffee">md5 = require <span class="hljs-symbol">'md</span>5'
|
||||
|
||||
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyMessageSidebar</span> <span class="hljs-keyword"><span class="hljs-keyword">extends</span></span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span>
|
||||
</span> <span class="hljs-annotation">@displayName</span>: <span class="hljs-symbol">'MyMessageSideba</span>r'
|
||||
|
||||
...
|
||||
|
||||
_renderContent: =>
|
||||
<div className=<span class="hljs-string">"header"</span>>
|
||||
{md5(<span class="hljs-annotation">@state</span>.contact.email)}
|
||||
</div>
|
||||
</code></pre>
|
||||
<blockquote>
|
||||
<p>JSX Tip: The <code>{..}</code> syntax is used for JavaScript expressions inside HTML elements. <a href="https://facebook.github.io/react/docs/jsx-in-depth.html">Learn more</a>.</p>
|
||||
</blockquote>
|
||||
<p>You should see the MD5 hash appear in the sidebar (after you reload N1):</p>
|
||||
<p><img class="gsg-center" src="images/sidebar-md5.png"/></p>
|
||||
<h3 id="let-s-render-">Let's Render!</h3>
|
||||
<p>Turning the MD5 hash into a Gravatar image is simple. We need to add an <code><img></code> tag to the rendered HTML:</p>
|
||||
<pre><code class="lang-coffee"><span class="xml">_renderContent =>
|
||||
<span class="hljs-tag"><<span class="hljs-title">div</span> <span class="hljs-attribute">className</span>=<span class="hljs-value">"header"</span>></span>
|
||||
<span class="hljs-tag"><<span class="hljs-title">img</span> <span class="hljs-attribute">src</span>=</span></span><span class="hljs-expression">{'<span class="hljs-variable">http</span>:/<span class="hljs-end-block">/www.gravatar.com</span><span class="hljs-end-block">/avatar</span>/' + <span class="hljs-variable">md</span>5(@<span class="hljs-variable">state.contact.email</span>)}</span><span class="xml"><span class="hljs-tag">/></span>
|
||||
<span class="hljs-tag"></<span class="hljs-title">div</span>></span></span>
|
||||
</code></pre>
|
||||
<p>Now the Gravatar image associated with the currently focused contact appears in the sidebar. If there's no image available, the Gravatar default will show; you can <a href="https://en.gravatar.com/site/implement/images/">add parameters to your image tag</a> to change the default behavior.</p>
|
||||
<p><img class="gsg-center" src="images/sidebar-gravatar.png"/></p>
|
||||
<h3 id="styling">Styling</h3>
|
||||
<p>Adding styles to our Gravatar image is a matter of editing <code>stylesheets/main.less</code> and applying the class to our <code>img</code> tag. Let's make it round:</p>
|
||||
<p><div class="filename">stylesheets/main.less</div></p>
|
||||
<pre><code class="lang-css"><span class="hljs-class">.gravatar</span> <span class="hljs-rules">{
|
||||
<span class="hljs-rule"><span class="hljs-attribute">border-radius</span>:<span class="hljs-value"> <span class="hljs-number">45px</span></span></span>;
|
||||
<span class="hljs-rule"><span class="hljs-attribute">border</span>:<span class="hljs-value"> <span class="hljs-number">2px</span> solid <span class="hljs-hexcolor">#ccc</span></span></span>;
|
||||
}</span>
|
||||
</code></pre>
|
||||
<p><div class="filename">lib/my-message-sidebar.cjsx</div></p>
|
||||
<pre><code class="lang-coffee">_renderContent =>
|
||||
gravatar = <span class="hljs-string">"http://www.gravatar.com/avatar/"</span> + md5(@<span class="hljs-keyword">state</span>.contact.email)
|
||||
|
||||
<span class="hljs-variable"><div className="header"></span>
|
||||
<span class="hljs-variable"><img src={gravatar} className="gravatar"/></span>
|
||||
<span class="hljs-variable"></div></span>
|
||||
</code></pre>
|
||||
<blockquote>
|
||||
<p>React Tip: Remember to use DOM property names, i.e. <code>className</code> instead of <code>class</code>.</p>
|
||||
</blockquote>
|
||||
<p>You'll see these styles reflected in your sidebar.</p>
|
||||
<p><img class="gsg-center" src="images/sidebar-style.png"/></p>
|
||||
<p>If you're a fan of using the Chrome Developer Tools to tinker with styles, no fear; they work in N1, too. Open them by going to <code>Developer > Toggle Developer Tools</code>. You'll also find them helpful for debugging in the event that your package isn't behaving as expected.</p>
|
||||
<hr/>
|
||||
|
||||
<h2 class="continue"><a href="getting-started-3">Continue this guide: adding a data store to your package</a></h2>
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
<h2 class="gsg-header">Step 3: Adding a Data Store</h2>
|
||||
|
||||
<p>Building on the <a href="getting-started-2">previous part</a> of our Getting Started guide, we're going to introduce a data store to give our sidebar superpowers.</p>
|
||||
<h2 id="stores-and-data-flow">Stores and Data Flow</h2>
|
||||
<p>The Nylas data model revolves around a central <code>DatabaseStore</code> and lightweight <code>Models</code> that represent data with a particular schema. This works a lot like ActiveRecord, SQLAlchemy and other "smart model" ORMs. See the <a href="database">Database</a> explanation for more details.</p>
|
||||
<p>Using the <a href="https://facebook.github.io/flux/docs/overview.html#structure-and-data-flow">Flux pattern</a> for data flow means that we set up our UI components to 'listen' to specific data stores. When those stores change, we update the state inside our component, and re-render the view.</p>
|
||||
<p>We've already used this (without realizing) in the <a href="getting-started-2">Gravatar sidebar example</a>:</p>
|
||||
<pre><code class="lang-coffee"> componentDidMount: =>
|
||||
@unsubscribe = FocusedContactsStore.<span class="hljs-function"><span class="hljs-title">listen</span><span class="hljs-params">(@_onChange)</span></span>
|
||||
...
|
||||
_onChange: =>
|
||||
@<span class="hljs-function"><span class="hljs-title">setState</span><span class="hljs-params">(@_getStateFromStores()</span></span>)
|
||||
|
||||
_getStateFromStores: =>
|
||||
contact: FocusedContactsStore.<span class="hljs-function"><span class="hljs-title">focusedContact</span><span class="hljs-params">()</span></span>
|
||||
</code></pre>
|
||||
<p>In this case, the sidebar listens to the <code>FocusedContactsStore</code>, which updates when the person selected in the conversation changes. This triggers the <code>_onChange</code> method which updates the component state; this causes React to render the view with the new state.</p>
|
||||
<p>To add more depth to our sidebar package, we need to:</p>
|
||||
<ul>
|
||||
<li>Create our own data store which will listen to <code>FocusedContactsStore</code></li>
|
||||
<li>Extend our data store to do additional things with the contact data</li>
|
||||
<li>Update our sidebar to listen to, and display data from, the new store.</li>
|
||||
</ul>
|
||||
<p>In this guide, we'll fetch the GitHub profile for the currently focused contact and display a link to it, using the <a href="https://developer.github.com/v3/search/">GitHub API</a>.</p>
|
||||
<h2 id="creating-the-store">Creating the Store</h2>
|
||||
<p>The boilerplate to create a new store which listens to <code>FocusedContactsStore</code> looks like this:</p>
|
||||
<p><div class="filename">lib/github-user-store.coffee</div></p>
|
||||
<pre><code class="lang-coffee">Reflux = <span class="hljs-built_in">require</span> <span class="hljs-string">'reflux'</span>
|
||||
{FocusedContactsStore} = <span class="hljs-built_in">require</span> <span class="hljs-string">'nylas-exports'</span>
|
||||
|
||||
<span class="hljs-built_in">module</span>.exports =
|
||||
|
||||
GithubUserStore = Reflux.createStore
|
||||
|
||||
<span class="hljs-attribute">init</span>: <span class="hljs-function">-></span>
|
||||
<span class="hljs-property">@listenTo</span> FocusedContactsStore, <span class="hljs-property">@_onFocusedContactChanged</span>
|
||||
|
||||
<span class="hljs-attribute">_onFocusedContactChanged</span>: <span class="hljs-function">-></span>
|
||||
<span class="hljs-comment"># TBD - This is fired when the focused contact changes</span>
|
||||
<span class="hljs-property">@trigger</span>(@)
|
||||
</code></pre>
|
||||
<p>(Note: You'll need to set up the <code>reflux</code> dependency.)</p>
|
||||
<p>You should be able to drop this store into the sidebar example's <code>componentDidMount</code> method -- all it does is listen for the <code>FocusedContactsStore</code> to change, and then <code>trigger</code> its own event.</p>
|
||||
<p>Let's build this out to retrieve some new data based on the focused contact, and expose it via a UI component.</p>
|
||||
<h2 id="getting-data-in">Getting Data In</h2>
|
||||
<p>We'll expand the <code>_onFocusedContactChanged</code> method to do something when the focused contact changes. In this case, we'll see if there's a GitHub profile for that user, and display some information if there is.</p>
|
||||
<pre><code class="lang-coffee">request = <span class="hljs-built_in">require</span> <span class="hljs-string">'request'</span>
|
||||
|
||||
GithubUserStore = Reflux.createStore
|
||||
<span class="hljs-attribute">init</span>: <span class="hljs-function">-></span>
|
||||
<span class="hljs-property">@_profile</span> = <span class="hljs-literal">null</span>
|
||||
<span class="hljs-property">@listenTo</span> FocusedContactsStore, <span class="hljs-property">@_onFocusedContactChanged</span>
|
||||
|
||||
<span class="hljs-attribute">getProfile</span>: <span class="hljs-function">-></span>
|
||||
<span class="hljs-property">@_profile</span>
|
||||
|
||||
<span class="hljs-attribute">_onFocusedContactChanged</span>: <span class="hljs-function">-></span>
|
||||
<span class="hljs-comment"># Get the newly focused contact</span>
|
||||
contact = FocusedContactsStore.focusedContact()
|
||||
<span class="hljs-comment"># Clear the profile we're currently showing</span>
|
||||
<span class="hljs-property">@_profile</span> = <span class="hljs-literal">null</span>
|
||||
<span class="hljs-keyword">if</span> contact
|
||||
<span class="hljs-property">@_fetchGithubProfile</span>(contact.email)
|
||||
<span class="hljs-property">@trigger</span>(@)
|
||||
|
||||
<span class="hljs-attribute">_fetchGithubProfile</span>: <span class="hljs-function"><span class="hljs-params">(email)</span> -></span>
|
||||
<span class="hljs-property">@_makeRequest</span> <span class="hljs-string">"https://api.github.com/search/users?q=<span class="hljs-subst">#{email}</span>"</span>, <span class="hljs-function"><span class="hljs-params">(err, resp, data)</span> =></span>
|
||||
<span class="hljs-built_in">console</span>.warn(data.message) <span class="hljs-keyword">if</span> data.message?
|
||||
<span class="hljs-comment"># Make sure we actually got something back</span>
|
||||
github = data?.items?[<span class="hljs-number">0</span>] ? <span class="hljs-literal">false</span>
|
||||
<span class="hljs-keyword">if</span> github
|
||||
<span class="hljs-property">@_profile</span> = github
|
||||
<span class="hljs-built_in">console</span>.log(github)
|
||||
<span class="hljs-property">@trigger</span>(@)
|
||||
|
||||
<span class="hljs-attribute">_makeRequest</span>: <span class="hljs-function"><span class="hljs-params">(url, callback)</span> -></span>
|
||||
<span class="hljs-comment"># GitHub needs a User-Agent header. Also, parse responses as JSON.</span>
|
||||
request({<span class="hljs-attribute">url</span>: url, <span class="hljs-attribute">headers</span>: {<span class="hljs-string">'User-Agent'</span>: <span class="hljs-string">'request'</span>}, <span class="hljs-attribute">json</span>: <span class="hljs-literal">true</span>}, callback)
|
||||
</code></pre>
|
||||
<p>The <code>console.log</code> line should show the GitHub profile for a contact (if they have one!) inside the Developer Tools Console, which you can enable at <code>Developer > Toggle Developer Tools</code>.</p>
|
||||
<p>You may run into rate-limiting issues with the GitHub API; to avoid these, you can add <a href="https://developer.github.com/v3/#authentication">authentication</a> with a <a href="https://github.com/settings/tokens">pre-baked token</a> by modifying the HTTP request your store makes. <strong>Caution! Use this for local development only.</strong> You could also try implementing a simple cache to avoid making the same request multiple times.</p>
|
||||
<h2 id="display-time">Display Time</h2>
|
||||
<p>To display this new data in the sidebar, we need to make sure our component is listening to the store, and load the appropriate state when it changes.</p>
|
||||
<pre><code class="lang-coffee"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GithubSidebar</span> <span class="hljs-keyword"><span class="hljs-keyword">extends</span></span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span>
|
||||
</span> ...
|
||||
componentDidMount: =>
|
||||
<span class="hljs-annotation">@unsubscribe</span> = <span class="hljs-type">GithubUserStore</span>.listen(@_onChange)
|
||||
|
||||
_onChange: =>
|
||||
<span class="hljs-annotation">@setState</span>(@_getStateFromStores())
|
||||
|
||||
_getStateFromStores: =>
|
||||
github: <span class="hljs-type">GithubUserStore</span>.getProfile()
|
||||
</code></pre>
|
||||
<p>Now we can access <code>@state.github</code> (which is the GitHub user profile object), and display the information it contains by updating the <code>render</code> and <code>renderContent</code> methods.</p>
|
||||
<p>For example:</p>
|
||||
<pre><code class="lang-coffee"> _renderContent: =>
|
||||
<span class="hljs-tag"><<span class="hljs-title">img</span> <span class="hljs-attribute">className</span>=<span class="hljs-value">"github"</span> <span class="hljs-attribute">src</span>=<span class="hljs-value">{@state.github.avatar_url}</span>/></span> <span class="hljs-tag"><<span class="hljs-title">a</span> <span class="hljs-attribute">href</span>=<span class="hljs-value">{@state.github.html_url}</span>></span>GitHub<span class="hljs-tag"></<span class="hljs-title">a</span>></span>
|
||||
</code></pre>
|
||||
<h2 id="extending-the-store">Extending The Store</h2>
|
||||
<p>To make this package more compelling, we can extend the store to make further API requests and fetch more data about the user. Passing this data back to the UI component follows exactly the same pattern as the barebones data shown above, so we'll leave it as an exercise for the reader. :)</p>
|
||||
<blockquote>
|
||||
<p>You can find a more extensive version of this example in our <a href="https://github.com/nylas/edgehill-plugins/tree/master/sidebar-github-profile">sample packages repository</a>.</p>
|
||||
</blockquote>
|
||||
|
||||
</div>
|
|
@ -22,7 +22,7 @@ ComponentRegistry<span class="hljs-class">.register</span> NotificationsStickyBa
|
|||
location: WorkspaceStore<span class="hljs-class">.Sheet</span><span class="hljs-class">.Threads</span><span class="hljs-class">.Header</span>
|
||||
</code></pre>
|
||||
<p>Each column is laid out as a CSS Flexbox, making them extremely flexible. For more about layout using Flexbox, see Working with Flexbox.</p>
|
||||
<h3 id="toolbars">Toolbars</h3>
|
||||
<p>###Toolbars</p>
|
||||
<p>Toolbars in N1 are also powered by the <a href='componentregistry.html'>ComponentRegistry</a>. Though toolbars appear to be a single unit at the top of a sheet, they are divided into columns with the same widths as the columns in the sheet beneath them.</p>
|
||||
<p><img src="./images/toolbar.png"></p>
|
||||
<p>Each Toolbar column is laid out using <a href='flexbox.html'>Flexbox</a>. You can control where toolbar elements appear within the column using the CSS <code>order</code> attribute. To make it easy to position toolbar items on the left, right, or center of a column, we've added two "spacer" elements with <code>order:50</code> and <code>order:-50</code> that evenly use up available space. Other CSS attributes allow you to control whether your items shrink or expand as the column's size changes.</p>
|
||||
|
|
|
@ -22,9 +22,9 @@ components by providing the <code>headerComponents</code> and <code>footerCompon
|
|||
These items are nested within <code>.header-container</code>. and <code>.footer-container</code>,
|
||||
and you can customize their appearance by providing CSS selectors scoped to your
|
||||
component's Menu instance:</p>
|
||||
<pre><code class="lang-css">.<span class="hljs-keyword">template</span>-picker .menu .header-container {
|
||||
height: <span class="hljs-number">100</span>px;
|
||||
}
|
||||
<pre><code class="lang-css"><span class="hljs-class">.template-picker</span> <span class="hljs-class">.menu</span> <span class="hljs-class">.header-container</span> <span class="hljs-rules">{
|
||||
<span class="hljs-rule"><span class="hljs-attribute">height</span>:<span class="hljs-value"> <span class="hljs-number">100px</span></span></span>;
|
||||
}</span>
|
||||
</code></pre>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -21,8 +21,8 @@ and other settings:</p>
|
|||
</code></pre>
|
||||
<p>The MultiselectActionBar uses the <code>ComponentRegistry</code> to find items to display for the given
|
||||
collection name. To add an item to the bar created in the example above, register it like this:</p>
|
||||
<pre><code class="lang-coffee">ComponentRegistry<span class="hljs-class">.register</span> ThreadBulkRemoveButton,
|
||||
role: <span class="hljs-string">'thread:BulkAction'</span>
|
||||
<pre><code class="lang-coffee"><span class="hljs-tag">ComponentRegistry</span><span class="hljs-class">.register</span> <span class="hljs-tag">ThreadBulkRemoveButton</span>,
|
||||
<span class="hljs-rule"><span class="hljs-attribute">role</span>:<span class="hljs-value"> <span class="hljs-string">'thread:BulkAction'</span></span></span>
|
||||
</code></pre>
|
||||
</p>
|
||||
</div>
|
||||
|
|
9
docs/README.html
Normal file
9
docs/README.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: docs
|
||||
title: README.md
|
||||
---
|
||||
<h1 id="n1-documentation">N1 Documentation</h1>
|
||||
<p>For the full documentation (which includes these guides), go to:
|
||||
<a href="https://nylas.github.io/N1/docs/">https://nylas.github.io/N1/docs/</a></p>
|
||||
<p>To see annotated package examples, go to: <a href="https://nylas.github.io/N1/examples/">https://nylas.github.io/N1/examples/</a></p>
|
||||
|
|
@ -53,13 +53,13 @@ title: Interface Components
|
|||
</code></pre>
|
||||
</li>
|
||||
<li><p>Add a component to the action bar at the bottom of the Composer:</p>
|
||||
<pre><code class="lang-coffee"> ComponentRegistry<span class="hljs-class">.register</span> TemplatePicker,
|
||||
role: <span class="hljs-string">'Composer:ActionButton'</span>
|
||||
<pre><code class="lang-coffee"> <span class="hljs-tag">ComponentRegistry</span><span class="hljs-class">.register</span> <span class="hljs-tag">TemplatePicker</span>,
|
||||
<span class="hljs-rule"><span class="hljs-attribute">role</span>:<span class="hljs-value"> <span class="hljs-string">'Composer:ActionButton'</span></span></span>
|
||||
</code></pre>
|
||||
</li>
|
||||
<li><p>Replace the <code>Participants</code> component that ships with N1 to display thread participants on your own:</p>
|
||||
<pre><code class="lang-coffee"> ComponentRegistry<span class="hljs-class">.register</span> ParticipantsWithStatusDots,
|
||||
role: <span class="hljs-string">'Participants'</span>
|
||||
<pre><code class="lang-coffee"> <span class="hljs-tag">ComponentRegistry</span><span class="hljs-class">.register</span> <span class="hljs-tag">ParticipantsWithStatusDots</span>,
|
||||
<span class="hljs-rule"><span class="hljs-attribute">role</span>:<span class="hljs-value"> <span class="hljs-string">'Participants'</span></span></span>
|
||||
</code></pre>
|
||||
</li>
|
||||
</ol>
|
||||
|
|
|
@ -24,12 +24,12 @@ main window via IPC.</p>
|
|||
Actions.queueTask(<span class="hljs-keyword">new</span> ChangeStarredTask(<span class="hljs-attribute">thread</span>: <span class="hljs-property">@_thread</span>, <span class="hljs-attribute">starred</span>: <span class="hljs-literal">true</span>))
|
||||
</code></pre>
|
||||
<h2 id="dequeueing-a-task">Dequeueing a Task</h2>
|
||||
<pre><code class="lang-coffee"><span class="hljs-type">Actions</span>.dequeueMatchingTask({
|
||||
<span class="hljs-class"><span class="hljs-keyword">type</span>:</span> <span class="hljs-symbol">'FileUploadTas</span>k',
|
||||
<pre><code class="lang-coffee"><span class="hljs-tag">Actions</span><span class="hljs-class">.dequeueMatchingTask</span>(<span class="hljs-rules">{
|
||||
<span class="hljs-rule"><span class="hljs-attribute">type</span>:<span class="hljs-value"> <span class="hljs-string">'FileUploadTask'</span>,
|
||||
matching: {
|
||||
filePath: uploadData.filePath
|
||||
}
|
||||
})
|
||||
})</span></span></span>
|
||||
</code></pre>
|
||||
<h2 id="creating-tasks">Creating Tasks</h2>
|
||||
<p>Support for creating custom <a href='task.html'>Task</a> subclasses in third-party packages is coming soon.
|
||||
|
|
|
@ -2,12 +2,11 @@
|
|||
layout: docs
|
||||
title: Writing Specs
|
||||
---
|
||||
<h1 id="writing-specs">Writing specs</h1>
|
||||
<p>Nylas uses <a href="http://jasmine.github.io/1.3/introduction.html">Jasmine</a> as its spec framework. As a package developer, you can write specs using Jasmine 1.3 and get some quick wins. Jasmine specs can be run in N1 directly from the Developer menu, and the test environment provides you with helpful stubs. You can also require your own test framework, or use Jasmine for integration tests and your own framework for your existing business logic.</p>
|
||||
<p>This documentation describes using <a href="http://jasmine.github.io/1.3/introduction.html">Jasmine 1.3</a> to write specs for a Nylas package.</p>
|
||||
<h4 id="running-specs">Running Specs</h4>
|
||||
<h3 id="running-specs">Running Specs</h3>
|
||||
<p>You can run your package specs from <code>Developer > Run Package Specs...</code>. Once you've opened the spec window, you can see output and re-run your specs by clicking <code>Reload Specs</code>.</p>
|
||||
<h4 id="writing-specs">Writing Specs</h4>
|
||||
<h3 id="writing-specs">Writing Specs</h3>
|
||||
<p>To create specs, place <code>js</code>, <code>coffee</code>, or <code>cjsx</code> files in the <code>spec</code> directory of your package. Spec files must end with the <code>-spec</code> suffix.</p>
|
||||
<p>Here's an annotated look at a typical Jasmine spec:</p>
|
||||
<pre><code class="lang-coffee"><span class="hljs-comment"># The `describe` method takes two arguments, a description and a function. If the description</span>
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Add table
Reference in a new issue