Mailspring/docs/Actions.html
2015-10-03 12:57:50 -07:00

261 lines
17 KiB
HTML

---
layout: docs
title: Actions
edit_url: "https://github.com/nylas/N1/blob/master/src/flux/actions.coffee"
---
<h2>Summary</h2>
<div class="markdown-from-sourecode">
<p><p>In the Flux <a href='Architecture.html'>Application Architecture</a>, almost every user action
is translated into an Action object and fired globally. Stores in the app observe
these actions and perform business logic. This loose coupling means that your
packages can observe actions and perform additional logic, or fire actions which
the rest of the app will handle.</p>
<p>In Reflux, each {Action} is an independent object that acts as an event emitter.
You can listen to an Action, or invoke it as a function to fire it.</p>
<h2 id="action-scopes">Action Scopes</h2>
<p>N1 is a multi-window application. The <code>scope</code> of an Action dictates
how it propogates between windows.</p>
<ul>
<li><strong>Global</strong>: These actions can be listened to from any window and fired from any
window. The action is sent from the originating window to all other windows via
IPC, so they should be used with care. Firing this action from anywhere will
cause all listeners in all windows to fire.</li>
<li><strong>Main Window</strong>: You can fire these actions in any window. They&#39;ll be sent
to the main window and triggered there.</li>
<li><strong>Window</strong>: These actions only trigger listeners in the window they&#39;re fired in.</li>
</ul>
<h2 id="firing-actions">Firing Actions</h2>
<pre><code class="lang-coffee"><span class="hljs-tag">Actions</span><span class="hljs-class">.postNotification</span>({<span class="hljs-attribute">message</span>: <span class="hljs-string">"Removed Thread"</span>, <span class="hljs-attribute">type</span>: <span class="hljs-string">'success'</span>})
<span class="hljs-tag">Actions</span><span class="hljs-class">.queueTask</span>(new <span class="hljs-function">ChangeStarredTask</span>(<span class="hljs-attribute">thread</span>: <span class="hljs-variable">@_thread</span>, <span class="hljs-attribute">starred</span>: true))
</code></pre>
<h2 id="listening-for-actions">Listening for Actions</h2>
<p>If you&#39;re using Reflux to create your own Store, you can use the <code>listenTo</code>
convenience method to listen for an Action. If you&#39;re creating your own class
that is not a Store, you can still use the <code>listen</code> method provided by Reflux:</p>
<pre><code class="lang-coffee"><span class="hljs-attribute">setup</span>: <span class="hljs-function">-&gt;</span>
<span class="hljs-property">@unlisten</span> = Actions.didPassivelyReceiveNewModels.listen(<span class="hljs-property">@onNewMailReceived</span>, @)
<span class="hljs-attribute">onNewMailReceived</span>: <span class="hljs-function"><span class="hljs-params">(data)</span> -&gt;</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"You've got mail!"</span>, data)
<span class="hljs-attribute">teardown</span>: <span class="hljs-function">-&gt;</span>
<span class="hljs-property">@unlisten</span>()
</code></pre>
</p>
</div>
<ul>
</ul>
<h3>Class Properties</h3>
<h4 id=didPassivelyReceiveNewModels>didPassivelyReceiveNewModels <a href="#didPassivelyReceiveNewModels" class="link"></a></h4>
<p><p>Fired when the Nylas API Connector receives new data from the API.</p>
<p><em>Scope: Global</em></p>
<p>Receives an <a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/object'>Object</a> of <a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/array'>Array</a>s of <a href='model.html'>Model</a>s, for example:</p>
<pre><code class="lang-json">{
'thread': <span class="hljs-annotation">[&lt;Thread&gt;, &lt;Thread&gt;]</span>
'contact': <span class="hljs-annotation">[&lt;Contact&gt;]</span>
}
</code></pre>
</p>
<h4 id=queueTask>queueTask <a href="#queueTask" class="link"></a></h4>
<p><p>Queue a <a href='task.html'>Task</a> object to the <a href='taskqueue.html'>TaskQueue</a>.</p>
<p><em>Scope: Work Window</em></p>
</p>
<h4 id=dequeueAllTasks>dequeueAllTasks <a href="#dequeueAllTasks" class="link"></a></h4>
<p><p>Dequeue all <a href='task.html'>Task</a>s from the <a href='taskqueue.html'>TaskQueue</a>. Use with care.</p>
<p><em>Scope: Work Window</em></p>
</p>
<h4 id=dequeueMatchingTask>dequeueMatchingTask <a href="#dequeueMatchingTask" class="link"></a></h4>
<p><p>Dequeue a <a href='task.html'>Task</a> matching the description provided.</p>
<p><em>Scope: Work Window</em></p>
</p>
<h4 id=retryInitialSync>retryInitialSync <a href="#retryInitialSync" class="link"></a></h4>
<p><p>Retry the initial sync</p>
<p><em>Scope: Work Window</em></p>
</p>
<h4 id=openPreferences>openPreferences <a href="#openPreferences" class="link"></a></h4>
<p><p>Open the preferences window. Pass an object with a tab name
(ie: <code>{tab: &#39;Accounts&#39;}</code>) to open a specific panel.</p>
<p><em>Scope: Window</em></p>
</p>
<h4 id=registerPreferencesTab>registerPreferencesTab <a href="#registerPreferencesTab" class="link"></a></h4>
<p><p>Register a preferences tab, usually applied in Preferences window</p>
<p><em>Scope: Window</em></p>
</p>
<h4 id=clearDeveloperConsole>clearDeveloperConsole <a href="#clearDeveloperConsole" class="link"></a></h4>
<p><p>Clear the developer console for the current window.</p>
<p><em>Scope: Window</em></p>
</p>
<h4 id=selectAccountId>selectAccountId <a href="#selectAccountId" class="link"></a></h4>
<p><p>Select the provided account ID in the current window.</p>
<p><em>Scope: Window</em></p>
</p>
<h4 id=selectRootSheet>selectRootSheet <a href="#selectRootSheet" class="link"></a></h4>
<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><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><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
<code>keyboard focus</code> element in lists and other components, but does not change
the focused DOM element.</p>
<p><em>Scope: Window</em></p>
<pre><code>Actions.<span class="hljs-function"><span class="hljs-title">setCursorPosition</span><span class="hljs-params">(collection: <span class="hljs-string">'thread'</span>, item: &lt;Thread&gt;)</span></span>
</code></pre></p>
<h4 id=setFocus>setFocus <a href="#setFocus" class="link"></a></h4>
<p><p>Focus on an item in a collection. This action changes the selection
in lists and other components, but does not change the focused DOM element.</p>
<p><em>Scope: Window</em></p>
<pre><code>Actions.<span class="hljs-function"><span class="hljs-title">setFocus</span><span class="hljs-params">(collection: <span class="hljs-string">'thread'</span>, item: &lt;Thread&gt;)</span></span>
</code></pre></p>
<h4 id=focusMailView>focusMailView <a href="#focusMailView" class="link"></a></h4>
<p><p>Focus the interface on a specific {Category}.</p>
<p><em>Scope: Window</em></p>
<pre><code>Actions.<span class="hljs-function"><span class="hljs-title">focusMailView</span><span class="hljs-params">(&lt;Category&gt;)</span></span>
</code></pre></p>
<h4 id=toggleMessageIdExpanded>toggleMessageIdExpanded <a href="#toggleMessageIdExpanded" class="link"></a></h4>
<p><p>If the message with the provided id is currently beign displayed in the
thread view, this action toggles whether it&#39;s full content or snippet is shown.</p>
<p><em>Scope: Window</em></p>
<pre><code><span class="hljs-keyword">message</span> = &lt;<span class="hljs-keyword">Message</span>&gt;
Actions.toggleMessageIdExpanded(<span class="hljs-keyword">message</span>.id)
</code></pre></p>
<h4 id=composeReply>composeReply <a href="#composeReply" class="link"></a></h4>
<p><p>Create a new reply to the provided threadId and messageId. Note that
this action does not focus on the thread, so you may not be able to see the new draft
unless you also call <a href='#setFocus'>setFocus</a>.</p>
<p><em>Scope: Window</em></p>
<pre><code><span class="hljs-comment"># Compose a reply to the last message in the thread</span>
Actions.composeReply({threadId: <span class="hljs-string">'123'</span>})
<span class="hljs-comment"># Compose a reply to a specific message in the thread</span>
Actions.composeReply({threadId: <span class="hljs-string">'123'</span>, messageId: <span class="hljs-string">'123'</span>})
</code></pre></p>
<h4 id=composeForward>composeForward <a href="#composeForward" class="link"></a></h4>
<p><p>Create a new draft for forwarding the provided threadId and messageId. See
<a href='#composeReply'>composeReply</a> for parameters and behavior.</p>
<p><em>Scope: Window</em></p>
</p>
<h4 id=composeReplyAll>composeReplyAll <a href="#composeReplyAll" class="link"></a></h4>
<p><p>Create a new draft and &quot;reply all&quot; to the provided threadId and messageId. See
<a href='#composeReply'>composeReply</a> for parameters and behavior.</p>
<p><em>Scope: Window</em></p>
</p>
<h4 id=composePopoutDraft>composePopoutDraft <a href="#composePopoutDraft" class="link"></a></h4>
<p><p>Pop out the draft with the provided ID so the user can edit it in another
window.</p>
<p><em>Scope: Window</em></p>
<pre><code>messageId = <span class="hljs-string">'123'</span>
Actions.<span class="hljs-function"><span class="hljs-title">composePopoutDraft</span><span class="hljs-params">(messageId)</span></span>
</code></pre></p>
<h4 id=composeNewBlankDraft>composeNewBlankDraft <a href="#composeNewBlankDraft" class="link"></a></h4>
<p><p>Open a new composer window for creating a new draft from scratch.</p>
<p><em>Scope: Window</em></p>
<pre><code>Actions.<span class="hljs-function"><span class="hljs-title">composeNewBlankDraft</span><span class="hljs-params">()</span></span>
</code></pre></p>
<h4 id=sendDraft>sendDraft <a href="#sendDraft" class="link"></a></h4>
<p><p>Send the draft with the given ID. This Action is handled by the <a href='draftstore.html'>DraftStore</a>,
which finalizes the <a href='draftchangeset.html'>DraftChangeSet</a> and allows <a href='draftstoreextension.html'>DraftStoreExtension</a>s to display
warnings and do post-processing. To change send behavior, you should consider using
one of these objects rather than listening for the {sendDraft} action.</p>
<p><em>Scope: Window</em></p>
<pre><code>Actions.<span class="hljs-function"><span class="hljs-title">sendDraft</span><span class="hljs-params">(<span class="hljs-string">'123'</span>)</span></span>
</code></pre></p>
<h4 id=destroyDraft>destroyDraft <a href="#destroyDraft" class="link"></a></h4>
<p><p>Destroys the draft with the given ID. This Action is handled by the <a href='draftstore.html'>DraftStore</a>,
and does not display any confirmation UI.</p>
<p><em>Scope: Window</em></p>
</p>
<h4 id=removeCurrentlyFocusedThread>removeCurrentlyFocusedThread <a href="#removeCurrentlyFocusedThread" class="link"></a></h4>
<p><p>Remove the currently focused <a href='thread.html'>Thread</a>.</p>
<p><em>Scope: Window</em></p>
</p>
<h4 id=removeSelection>removeSelection <a href="#removeSelection" class="link"></a></h4>
<p><p>Removes the Thread objects currently selected in the app&#39;s main thread list.</p>
<p><em>Scope: Window</em></p>
</p>
<h4 id=searchQueryChanged>searchQueryChanged <a href="#searchQueryChanged" class="link"></a></h4>
<p><p>Updates the search query in the app&#39;s main search bar with the provided query text.</p>
<p><em>Scope: Window</em></p>
<pre><code>Actions.<span class="hljs-function"><span class="hljs-title">searchQueryChanged</span><span class="hljs-params">(<span class="hljs-string">"New Search Query"</span>)</span></span>
</code></pre></p>
<h4 id=searchQueryCommitted>searchQueryCommitted <a href="#searchQueryCommitted" class="link"></a></h4>
<p><p>Submits a search with the provided query text. Unlike <code>searchQueryChanged</code>, this
action immediately performs a search.</p>
<p><em>Scope: Window</em></p>
<pre><code>Actions.<span class="hljs-function"><span class="hljs-title">searchQueryCommitted</span><span class="hljs-params">(<span class="hljs-string">"New Search Query"</span>)</span></span>
</code></pre></p>
<h4 id=RSVPEvent>RSVPEvent <a href="#RSVPEvent" class="link"></a></h4>
<p><p>Submits the user&#39;s response to an RSVP event.</p>
<p><em>Scope: Window</em></p>
</p>
<h4 id=postNotification>postNotification <a href="#postNotification" class="link"></a></h4>
<p><p>Fire to display an in-window notification to the user in the app&#39;s standard
notification interface.</p>
<p><em>Scope: Global</em></p>
<pre><code><span class="hljs-comment"># A simple notification</span>
Actions.postNotification({message: <span class="hljs-string">"Removed Thread"</span>, <span class="hljs-built_in">type</span>: <span class="hljs-string">'success'</span>})
<span class="hljs-comment"># A sticky notification with actions</span>
NOTIF_ACTION_YES = <span class="hljs-string">'YES'</span>
NOTIF_ACTION_NO = <span class="hljs-string">'NO'</span>
Actions.postNotification
<span class="hljs-built_in">type</span>: <span class="hljs-string">'info'</span>,
sticky: <span class="hljs-literal">true</span>
message: <span class="hljs-string">"Thanks for trying out N1! Would you like to make it your default mail client?"</span>,
icon: <span class="hljs-string">'fa-inbox'</span>,
actions: [{
label: <span class="hljs-string">'Yes'</span>
id: NOTIF_ACTION_YES
},{
label: <span class="hljs-string">'Not Now'</span>
id: NOTIF_ACTION_NO
}]
</code></pre></p>
<h4 id=notificationActionTaken>notificationActionTaken <a href="#notificationActionTaken" class="link"></a></h4>
<p><p>Listen to this action to handle user interaction with notifications you
published via <code>postNotification</code>.</p>
<p><em>Scope: Global</em></p>
<pre><code><span class="hljs-variable">@_unlisten</span> = Actions.notificationActionTaken.<span class="hljs-function">listen</span>(<span class="hljs-variable">@_onActionTaken</span>, @)
<span class="hljs-attribute">_onActionTaken</span>: ({notification, action}) -&gt;
if action.id is NOTIF_ACTION_YES
# perform action
</code></pre></p>
<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><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>.
This action has no effect if the window is currently showing a root sheet.</p>
<p><em>Scope: Window</em></p>
</p>
<h4 id=pushSheet>pushSheet <a href="#pushSheet" class="link"></a></h4>
<p><p>Push a sheet of a specific type onto the Sheet stack maintained by the
<a href='workspacestore.html'>WorkspaceStore</a>. Note that sheets have no state. To show a <em>specific</em> thread,
you should push a Thread sheet and call <code>setFocus</code> to select the thread.</p>
<p><em>Scope: Window</em></p>
<pre><code>WorkspaceStore.defineSheet <span class="hljs-string">'Thread'</span>, <span class="hljs-list">{}</span>,
list: [<span class="hljs-string">'MessageList'</span>, <span class="hljs-string">'MessageListSidebar'</span>]
...
@pushSheet(WorkspaceStore.Sheet.<span class="hljs-keyword">Thread</span>)
</code></pre></p>