mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-01-01 13:14:16 +08:00
feat(popout-threads) Add functionality to open threads in popout windows
Summary: Threads can now be opened in separate windows. This can be done via the popout icon next to the print icon, or by double-clicking the thread when in double- pane mode. Note that the single-click action is still fired, which is why double-clicking does not work in single-pane mode. The popout icon changes to a pop-in icon while in the popout window, to allow users to collapse it back into the main window. Test Plan: Tested locally Reviewers: evan, juan Reviewed By: juan Subscribers: sdw Differential Revision: https://phab.nylas.com/D3332
This commit is contained in:
parent
f409160273
commit
1c675935a7
22 changed files with 121 additions and 22 deletions
|
@ -13,6 +13,7 @@
|
|||
"windowTypes": {
|
||||
"default": true,
|
||||
"composer": true,
|
||||
"composer-preload": true
|
||||
"composer-preload": true,
|
||||
"thread-popout": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
},
|
||||
"windowTypes": {
|
||||
"default": true,
|
||||
"composer": true
|
||||
"composer": true,
|
||||
"thread-popout": true
|
||||
},
|
||||
"license": "GPL-3.0"
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
},
|
||||
"windowTypes": {
|
||||
"default": true,
|
||||
"composer": true
|
||||
"composer": true,
|
||||
"thread-popout": true
|
||||
},
|
||||
"dependencies": {
|
||||
"marked": "^0.3",
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
},
|
||||
"windowTypes": {
|
||||
"default": true,
|
||||
"composer": true
|
||||
"composer": true,
|
||||
"thread-popout": true
|
||||
},
|
||||
"dependencies": {
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
},
|
||||
"windowTypes": {
|
||||
"default": true,
|
||||
"composer": true
|
||||
"composer": true,
|
||||
"thread-popout": true
|
||||
},
|
||||
"dependencies": {
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
},
|
||||
"windowTypes": {
|
||||
"default": true,
|
||||
"composer": true
|
||||
"composer": true,
|
||||
"thread-popout": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
},
|
||||
"windowTypes": {
|
||||
"default": true,
|
||||
"composer": true
|
||||
"composer": true,
|
||||
"thread-popout": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,6 +115,10 @@ export function activate() {
|
|||
ComponentRegistry.register(ComposeButton, {
|
||||
location: WorkspaceStore.Location.RootSidebar.Toolbar,
|
||||
});
|
||||
} else if (NylasEnv.isThreadWindow()) {
|
||||
ComponentRegistry.register(ComposerViewForDraftClientId, {
|
||||
role: 'Composer',
|
||||
});
|
||||
} else {
|
||||
NylasEnv.getCurrentWindow().setMinimumSize(480, 250);
|
||||
ComponentRegistry.register(ComposerWithWindowProps, {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
"windowTypes": {
|
||||
"default": true,
|
||||
"composer": true,
|
||||
"composer-preload": true
|
||||
"composer-preload": true,
|
||||
"thread-popout": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
"license": "GPL-3.0",
|
||||
"windowTypes": {
|
||||
"default": true,
|
||||
"composer": true
|
||||
"composer": true,
|
||||
"thread-popout": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
{ComponentRegistry,
|
||||
ExtensionRegistry,
|
||||
WorkspaceStore} = require 'nylas-exports'
|
||||
WorkspaceStore,
|
||||
DatabaseStore,
|
||||
Actions,
|
||||
Thread} = require 'nylas-exports'
|
||||
|
||||
MessageList = require("./message-list")
|
||||
MessageListHiddenMessagesToggle = require('./message-list-hidden-messages-toggle').default
|
||||
|
@ -10,18 +13,27 @@ SidebarParticipantPicker = require('./sidebar-participant-picker').default
|
|||
|
||||
module.exports =
|
||||
activate: ->
|
||||
# Register Message List Actions we provide globally
|
||||
ComponentRegistry.register MessageList,
|
||||
location: WorkspaceStore.Location.MessageList
|
||||
if NylasEnv.isMainWindow()
|
||||
# Register Message List Actions we provide globally
|
||||
ComponentRegistry.register MessageList,
|
||||
location: WorkspaceStore.Location.MessageList
|
||||
|
||||
ComponentRegistry.register SidebarParticipantPicker,
|
||||
location: WorkspaceStore.Location.MessageListSidebar
|
||||
ComponentRegistry.register SidebarParticipantPicker,
|
||||
location: WorkspaceStore.Location.MessageListSidebar
|
||||
|
||||
ComponentRegistry.register SidebarPluginContainer,
|
||||
location: WorkspaceStore.Location.MessageListSidebar
|
||||
ComponentRegistry.register SidebarPluginContainer,
|
||||
location: WorkspaceStore.Location.MessageListSidebar
|
||||
|
||||
ComponentRegistry.register MessageListHiddenMessagesToggle,
|
||||
role: 'MessageListHeaders'
|
||||
ComponentRegistry.register MessageListHiddenMessagesToggle,
|
||||
role: 'MessageListHeaders'
|
||||
else
|
||||
# This is for the thread-popout window.
|
||||
ComponentRegistry.register(MessageList, {location: WorkspaceStore.Location.Center})
|
||||
threadId = NylasEnv.getWindowProps().threadId;
|
||||
# We need to locate the thread and focus it so that the MessageList displays it
|
||||
DatabaseStore.find(Thread, threadId).then((thread) =>
|
||||
Actions.setFocus({collection: 'thread', item: thread})
|
||||
)
|
||||
|
||||
deactivate: ->
|
||||
ComponentRegistry.unregister MessageList
|
||||
|
|
|
@ -204,6 +204,7 @@ class MessageList extends React.Component
|
|||
<div onClick={@_onPrintThread}>
|
||||
<RetinaImg name="print.png" title="Print Thread" mode={RetinaImg.Mode.ContentIsMask}/>
|
||||
</div>
|
||||
{@_renderPopoutToggle()}
|
||||
</div>
|
||||
|
||||
_renderExpandToggle: =>
|
||||
|
@ -218,6 +219,17 @@ class MessageList extends React.Component
|
|||
<RetinaImg name={"collapse.png"} title={"Collapse All"} mode={RetinaImg.Mode.ContentIsMask}/>
|
||||
</div>
|
||||
|
||||
_renderPopoutToggle: =>
|
||||
if NylasEnv.isThreadWindow()
|
||||
<div onClick={@_onPopThreadIn}>
|
||||
<RetinaImg name="thread-popin.png" title="Pop thread in" mode={RetinaImg.Mode.ContentIsMask}/>
|
||||
</div>
|
||||
else
|
||||
<div onClick={@_onPopoutThread}>
|
||||
<RetinaImg name="thread-popout.png" title="Popout thread" mode={RetinaImg.Mode.ContentIsMask}/>
|
||||
</div>
|
||||
|
||||
|
||||
_renderReplyArea: =>
|
||||
<div className="footer-reply-area-wrap" onClick={@_onClickReplyArea} key='reply-area'>
|
||||
<div className="footer-reply-area">
|
||||
|
@ -250,6 +262,18 @@ class MessageList extends React.Component
|
|||
node = ReactDOM.findDOMNode(@)
|
||||
Actions.printThread(@state.currentThread, node.innerHTML)
|
||||
|
||||
_onPopThreadIn: =>
|
||||
return unless @state.currentThread
|
||||
Actions.focusThreadMainWindow(@state.currentThread)
|
||||
NylasEnv.close()
|
||||
|
||||
_onPopoutThread: =>
|
||||
return unless @state.currentThread
|
||||
Actions.popoutThread(@state.currentThread)
|
||||
# This returns the single-pane view to the inbox, and does nothing for
|
||||
# double-pane view because we're at the root sheet.
|
||||
Actions.popSheet()
|
||||
|
||||
_onClickReplyArea: =>
|
||||
return unless @state.currentThread
|
||||
Actions.composeReply({
|
||||
|
|
|
@ -7,5 +7,9 @@
|
|||
"private": true,
|
||||
"engines": {
|
||||
"nylas": "*"
|
||||
},
|
||||
"windowTypes": {
|
||||
"default": true,
|
||||
"thread-popout": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
},
|
||||
"windowTypes": {
|
||||
"default": true,
|
||||
"composer": true
|
||||
"composer": true,
|
||||
"thread-popout": true
|
||||
},
|
||||
"dependencies": {
|
||||
"tld": "^0.0.2"
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
},
|
||||
"windowTypes": {
|
||||
"default": true,
|
||||
"composer": true
|
||||
"composer": true,
|
||||
"thread-popout": true
|
||||
},
|
||||
"dependencies": {
|
||||
}
|
||||
|
|
|
@ -101,6 +101,7 @@ class ThreadList extends React.Component
|
|||
scrollTooltipComponent={ThreadListScrollTooltip}
|
||||
emptyComponent={EmptyListState}
|
||||
keymapHandlers={@_keymapHandlers()}
|
||||
onDoubleClick={(thread) -> Actions.popoutThread(thread)}
|
||||
onDragStart={@_onDragStart}
|
||||
onDragEnd={@_onDragEnd}
|
||||
draggable="true" />
|
||||
|
|
|
@ -305,6 +305,30 @@ class Actions
|
|||
###
|
||||
@printThread: ActionScopeWindow
|
||||
|
||||
###
|
||||
Public: Display the thread in a new popout window
|
||||
|
||||
*Scope: Window*
|
||||
|
||||
```
|
||||
thread = <Thread>
|
||||
Actions.popoutThread(thread)
|
||||
```
|
||||
###
|
||||
@popoutThread: ActionScopeWindow
|
||||
|
||||
###
|
||||
Public: Display the thread in the main window
|
||||
|
||||
*Scope: Global*
|
||||
|
||||
```
|
||||
thread = <Thread>
|
||||
Actions.focusThreadMainWindow(thread)
|
||||
```
|
||||
###
|
||||
@focusThreadMainWindow: ActionScopeGlobal
|
||||
|
||||
###
|
||||
Public: Create a new reply to the provided threadId and messageId and populate
|
||||
it with the body provided.
|
||||
|
|
|
@ -107,6 +107,8 @@ class MessageStore extends NylasStore
|
|||
@listenTo Actions.toggleAllMessagesExpanded, @_onToggleAllMessagesExpanded
|
||||
@listenTo Actions.toggleHiddenMessages, @_onToggleHiddenMessages
|
||||
@listenTo FocusedPerspectiveStore, @_onPerspectiveChanged
|
||||
@listenTo Actions.popoutThread, @_onPopoutThread
|
||||
@listenTo Actions.focusThreadMainWindow, @_onFocusThreadMainWindow
|
||||
|
||||
_onPerspectiveChanged: =>
|
||||
@trigger()
|
||||
|
@ -313,6 +315,20 @@ class MessageStore extends NylasStore
|
|||
|
||||
items
|
||||
|
||||
_onPopoutThread: (thread) ->
|
||||
NylasEnv.newWindow
|
||||
title: false, # MessageList already displays the thread subject
|
||||
hidden: false,
|
||||
windowKey: "thread-#{thread.id}",
|
||||
windowType: 'thread-popout',
|
||||
windowProps: threadId: thread.id,
|
||||
|
||||
_onFocusThreadMainWindow: (thread) ->
|
||||
if NylasEnv.isMainWindow()
|
||||
Actions.setFocus({collection: 'thread', item: thread})
|
||||
NylasEnv.focus()
|
||||
|
||||
|
||||
store = new MessageStore()
|
||||
store.registerExtension = deprecate(
|
||||
'MessageStore.registerExtension',
|
||||
|
|
|
@ -360,6 +360,9 @@ class NylasEnvConstructor
|
|||
isComposerWindow: ->
|
||||
@getWindowType() in ["composer", "composer-preload"]
|
||||
|
||||
isThreadWindow: ->
|
||||
@getWindowType() is 'thread-popout'
|
||||
|
||||
getWindowType: ->
|
||||
@getLoadSettings().windowType
|
||||
|
||||
|
|
2
src/pro
2
src/pro
|
@ -1 +1 @@
|
|||
Subproject commit ddb1789abc9aa34ac9a3fb893e7ee71e7893af67
|
||||
Subproject commit 26431475c6590262a190e572d0717fd730827cff
|
BIN
static/images/message-list/thread-popin@2x.png
Normal file
BIN
static/images/message-list/thread-popin@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 678 B |
BIN
static/images/message-list/thread-popout@2x.png
Normal file
BIN
static/images/message-list/thread-popout@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 619 B |
Loading…
Reference in a new issue