mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-09-12 23:54:45 +08:00
fix(workspace): Support for hidden locations / columns
Summary: - New control will likely be shortlived - SDW mocking up replacement for when settings UI lands - New action for toggling location hidden - New rule for mail labels: can't remove "Sent" Test Plan: Run tests - none new atm Reviewers: evan Reviewed By: evan Differential Revision: https://phab.nylas.com/D1782
This commit is contained in:
parent
a559e3f89f
commit
b412c580fc
11 changed files with 89 additions and 18 deletions
|
@ -8,6 +8,7 @@ MessageItem = require "./message-item"
|
||||||
DraftStore,
|
DraftStore,
|
||||||
MessageStore,
|
MessageStore,
|
||||||
DatabaseStore,
|
DatabaseStore,
|
||||||
|
WorkspaceStore,
|
||||||
ComponentRegistry,
|
ComponentRegistry,
|
||||||
ChangeLabelsTask,
|
ChangeLabelsTask,
|
||||||
UpdateThreadsTask} = require("nylas-exports")
|
UpdateThreadsTask} = require("nylas-exports")
|
||||||
|
@ -20,6 +21,34 @@ MessageItem = require "./message-item"
|
||||||
MailLabel,
|
MailLabel,
|
||||||
InjectedComponent} = require('nylas-component-kit')
|
InjectedComponent} = require('nylas-component-kit')
|
||||||
|
|
||||||
|
class HideSidebarButton extends React.Component
|
||||||
|
constructor: (@props) ->
|
||||||
|
@column = WorkspaceStore.Location.MessageListSidebar
|
||||||
|
@state = @getStateFromStores()
|
||||||
|
|
||||||
|
componentDidMount: =>
|
||||||
|
@unlisten = WorkspaceStore.listen => @setState(@getStateFromStores())
|
||||||
|
|
||||||
|
componentWillUnmount: =>
|
||||||
|
@unlisten()
|
||||||
|
|
||||||
|
render: =>
|
||||||
|
if @state.hidden
|
||||||
|
contents = {label: 'Show Sidebar', name: 'icon-thread-showsidebar.png'}
|
||||||
|
else
|
||||||
|
contents = {label: 'Hide Sidebar', name: 'icon-thread-hidesidebar.png'}
|
||||||
|
|
||||||
|
<div className="hide-sidebar-button" style={@props.style} onClick={@_onClick}>
|
||||||
|
<span className="img-wrap"><RetinaImg name={contents.name} mode={RetinaImg.Mode.ContentIsMask}/></span>
|
||||||
|
{contents.label}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
_onClick: =>
|
||||||
|
Actions.toggleWorkspaceLocationHidden(@column)
|
||||||
|
|
||||||
|
getStateFromStores: =>
|
||||||
|
{hidden: WorkspaceStore.isLocationHidden(@column)}
|
||||||
|
|
||||||
class MessageListScrollTooltip extends React.Component
|
class MessageListScrollTooltip extends React.Component
|
||||||
@displayName: 'MessageListScrollTooltip'
|
@displayName: 'MessageListScrollTooltip'
|
||||||
@propTypes:
|
@propTypes:
|
||||||
|
@ -226,7 +255,7 @@ class MessageList extends React.Component
|
||||||
|
|
||||||
_renderSubject: ->
|
_renderSubject: ->
|
||||||
<div className="message-subject-wrap">
|
<div className="message-subject-wrap">
|
||||||
<div className="message-count">{@state.messages.length} {if @state.messages.length is 1 then "message" else "messages"}</div>
|
<HideSidebarButton style={float:'right'}/>
|
||||||
<span className="message-subject">{@state.currentThread?.subject}</span>
|
<span className="message-subject">{@state.currentThread?.subject}</span>
|
||||||
{@_renderLabels()}
|
{@_renderLabels()}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -49,6 +49,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hide-sidebar-button {
|
||||||
|
font-size: @font-size-small;
|
||||||
|
color: @text-color-subtle;
|
||||||
|
margin-left: @spacing-standard;
|
||||||
|
cursor:default;
|
||||||
|
.img-wrap {
|
||||||
|
margin-right: @spacing-half;
|
||||||
|
position: relative;
|
||||||
|
top: -1px;
|
||||||
|
}
|
||||||
|
img { background: @text-color-subtle; }
|
||||||
|
}
|
||||||
|
|
||||||
#message-list {
|
#message-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -64,7 +77,7 @@
|
||||||
width: calc(~"100% - 12px");
|
width: calc(~"100% - 12px");
|
||||||
max-width: @message-max-width;
|
max-width: @message-max-width;
|
||||||
margin: 11px auto 10px auto;
|
margin: 11px auto 10px auto;
|
||||||
padding: 0 20px;
|
padding-left: 20px;
|
||||||
-webkit-user-select: text;
|
-webkit-user-select: text;
|
||||||
line-height: @font-size-large * 1.8;
|
line-height: @font-size-large * 1.8;
|
||||||
}
|
}
|
||||||
|
@ -73,12 +86,6 @@
|
||||||
color: @text-color;
|
color: @text-color;
|
||||||
margin-right: @spacing-standard;
|
margin-right: @spacing-standard;
|
||||||
}
|
}
|
||||||
.message-count {
|
|
||||||
float: right;
|
|
||||||
font-size: @font-size-small;
|
|
||||||
color: @text-color-very-subtle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-list-headers {
|
.message-list-headers {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -21,7 +21,7 @@ class ModeToggle extends React.Component
|
||||||
return <div></div> unless @state.visible
|
return <div></div> unless @state.visible
|
||||||
|
|
||||||
<div className="btn btn-toolbar mode-toggle mode-#{@state.mode}"
|
<div className="btn btn-toolbar mode-toggle mode-#{@state.mode}"
|
||||||
style={order:51}
|
style={order:500}
|
||||||
onClick={@_onToggleMode}>
|
onClick={@_onToggleMode}>
|
||||||
<RetinaImg
|
<RetinaImg
|
||||||
name="toolbar-icon-toggle-pane.png"
|
name="toolbar-icon-toggle-pane.png"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
React = require 'react'
|
React = require 'react'
|
||||||
RetinaImg = require './retina-img'
|
RetinaImg = require './retina-img'
|
||||||
|
CategoryStore = require '../flux/stores/category-store'
|
||||||
|
|
||||||
class MailLabel extends React.Component
|
class MailLabel extends React.Component
|
||||||
@propTypes:
|
@propTypes:
|
||||||
|
@ -18,7 +19,7 @@ class MailLabel extends React.Component
|
||||||
content = @props.label.displayName
|
content = @props.label.displayName
|
||||||
|
|
||||||
x = null
|
x = null
|
||||||
if @props.onRemove
|
if @_removable()
|
||||||
classname += ' removable'
|
classname += ' removable'
|
||||||
content = <span className="inner">{content}</span>
|
content = <span className="inner">{content}</span>
|
||||||
x = <RetinaImg
|
x = <RetinaImg
|
||||||
|
@ -30,6 +31,8 @@ class MailLabel extends React.Component
|
||||||
|
|
||||||
<div className={classname} style={style}>{content}{x}</div>
|
<div className={classname} style={style}>{content}{x}</div>
|
||||||
|
|
||||||
_renderX: ->
|
_removable: ->
|
||||||
|
isLockedLabel = @props.label.name in CategoryStore.LockedCategoryNames
|
||||||
|
return @props.onRemove and not isLockedLabel
|
||||||
|
|
||||||
module.exports = MailLabel
|
module.exports = MailLabel
|
||||||
|
|
|
@ -175,6 +175,15 @@ class Actions
|
||||||
###
|
###
|
||||||
@selectLayoutMode: ActionScopeWindow
|
@selectLayoutMode: ActionScopeWindow
|
||||||
|
|
||||||
|
###
|
||||||
|
Public: Toggle whether a particular column is visible. Call this action
|
||||||
|
with one of the Sheet location constants:
|
||||||
|
|
||||||
|
```
|
||||||
|
Actions.toggleWorkspaceLocationHidden(WorkspaceStore.Location.MessageListSidebar)
|
||||||
|
```
|
||||||
|
###
|
||||||
|
@toggleWorkspaceLocationHidden: ActionScopeWindow
|
||||||
|
|
||||||
###
|
###
|
||||||
Public: Focus the keyboard on an item in a collection. This action moves the
|
Public: Focus the keyboard on an item in a collection. This action moves the
|
||||||
|
|
|
@ -30,6 +30,8 @@ class WorkspaceStore
|
||||||
@listenTo Actions.selectLayoutMode, @_onSelectLayoutMode
|
@listenTo Actions.selectLayoutMode, @_onSelectLayoutMode
|
||||||
@listenTo Actions.setFocus, @_onSetFocus
|
@listenTo Actions.setFocus, @_onSetFocus
|
||||||
|
|
||||||
|
@listenTo Actions.toggleWorkspaceLocationHidden, @_onToggleLocationHidden
|
||||||
|
|
||||||
@listenTo Actions.popSheet, @popSheet
|
@listenTo Actions.popSheet, @popSheet
|
||||||
@listenTo Actions.searchQueryCommitted, @popToRootSheet
|
@listenTo Actions.searchQueryCommitted, @popToRootSheet
|
||||||
|
|
||||||
|
@ -41,6 +43,7 @@ class WorkspaceStore
|
||||||
@Sheet = Sheet = {}
|
@Sheet = Sheet = {}
|
||||||
|
|
||||||
@_preferredLayoutMode = 'list'
|
@_preferredLayoutMode = 'list'
|
||||||
|
@_hiddenLocations = {}
|
||||||
@_sheetStack = []
|
@_sheetStack = []
|
||||||
|
|
||||||
if atom.isMainWindow()
|
if atom.isMainWindow()
|
||||||
|
@ -71,6 +74,16 @@ class WorkspaceStore
|
||||||
@_preferredLayoutMode = mode
|
@_preferredLayoutMode = mode
|
||||||
@trigger(@)
|
@trigger(@)
|
||||||
|
|
||||||
|
_onToggleLocationHidden: (location) =>
|
||||||
|
if not location.id
|
||||||
|
throw new Error("Actions.toggleWorkspaceLocationHidden - pass a WorkspaceStore.Location")
|
||||||
|
|
||||||
|
if @_hiddenLocations[location.id]
|
||||||
|
delete @_hiddenLocations[location.id]
|
||||||
|
else
|
||||||
|
@_hiddenLocations[location.id] = location
|
||||||
|
@trigger(@)
|
||||||
|
|
||||||
_onSetFocus: ({collection, item}) =>
|
_onSetFocus: ({collection, item}) =>
|
||||||
if collection is 'thread'
|
if collection is 'thread'
|
||||||
if @layoutMode() is 'list'
|
if @layoutMode() is 'list'
|
||||||
|
@ -101,22 +114,32 @@ class WorkspaceStore
|
||||||
else
|
else
|
||||||
root.supportedModes[0]
|
root.supportedModes[0]
|
||||||
|
|
||||||
# Returns The top {Sheet} in the current stack. Use this method to determine
|
# Public: Returns The top {Sheet} in the current stack. Use this method to determine
|
||||||
# the sheet the user is looking at.
|
# the sheet the user is looking at.
|
||||||
#
|
#
|
||||||
topSheet: =>
|
topSheet: =>
|
||||||
@_sheetStack[@_sheetStack.length - 1]
|
@_sheetStack[@_sheetStack.length - 1]
|
||||||
|
|
||||||
# Returns The {Sheet} at the root of the current stack.
|
# Public: Returns The {Sheet} at the root of the current stack.
|
||||||
#
|
#
|
||||||
rootSheet: =>
|
rootSheet: =>
|
||||||
@_sheetStack[0]
|
@_sheetStack[0]
|
||||||
|
|
||||||
# Returns an {Array<Sheet>} The stack of sheets
|
# Public: Returns an {Array<Sheet>} The stack of sheets
|
||||||
#
|
#
|
||||||
sheetStack: =>
|
sheetStack: =>
|
||||||
@_sheetStack
|
@_sheetStack
|
||||||
|
|
||||||
|
# Public: Returns an {Array} of locations that have been hidden.
|
||||||
|
#
|
||||||
|
hiddenLocations: =>
|
||||||
|
_.values(@_hiddenLocations)
|
||||||
|
|
||||||
|
# Public: Returns a {Boolean} indicating whether the location provided is hidden.
|
||||||
|
# You should provide one of the WorkspaceStore.Location constant values.
|
||||||
|
isLocationHidden: (loc) =>
|
||||||
|
@_hiddenLocations[loc.id]
|
||||||
|
|
||||||
###
|
###
|
||||||
Managing Sheets
|
Managing Sheets
|
||||||
###
|
###
|
||||||
|
|
|
@ -182,6 +182,7 @@ class Toolbar extends React.Component
|
||||||
# Add items registered to Regions in the current sheet
|
# Add items registered to Regions in the current sheet
|
||||||
if @props.data?.columns[state.mode]?
|
if @props.data?.columns[state.mode]?
|
||||||
for loc in @props.data.columns[state.mode]
|
for loc in @props.data.columns[state.mode]
|
||||||
|
continue if WorkspaceStore.isLocationHidden(loc)
|
||||||
entries = ComponentRegistry.findComponentsMatching({location: loc.Toolbar, mode: state.mode})
|
entries = ComponentRegistry.findComponentsMatching({location: loc.Toolbar, mode: state.mode})
|
||||||
state.columns.push(entries)
|
state.columns.push(entries)
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,7 @@ class Sheet extends React.Component
|
||||||
|
|
||||||
if @props.data?.columns[state.mode]?
|
if @props.data?.columns[state.mode]?
|
||||||
for location, idx in @props.data.columns[state.mode]
|
for location, idx in @props.data.columns[state.mode]
|
||||||
|
continue if WorkspaceStore.isLocationHidden(location)
|
||||||
entries = ComponentRegistry.findComponentsMatching({location: location, mode: state.mode})
|
entries = ComponentRegistry.findComponentsMatching({location: location, mode: state.mode})
|
||||||
maxWidth = _.reduce entries, ((m,component) -> Math.min(component.containerStyles?.maxWidth ? 10000, m)), 10000
|
maxWidth = _.reduce entries, ((m,component) -> Math.min(component.containerStyles?.maxWidth ? 10000, m)), 10000
|
||||||
minWidth = _.reduce entries, ((m,component) -> Math.max(component.containerStyles?.minWidth ? 0, m)), 0
|
minWidth = _.reduce entries, ((m,component) -> Math.max(component.containerStyles?.minWidth ? 0, m)), 0
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -203,14 +203,12 @@ body.is-blurred {
|
||||||
|
|
||||||
.btn-toolbar {
|
.btn-toolbar {
|
||||||
margin-top: @spacing-three-quarters;
|
margin-top: @spacing-three-quarters;
|
||||||
margin-left: @spacing-three-quarters;
|
|
||||||
margin-right: @spacing-three-quarters;
|
margin-right: @spacing-three-quarters;
|
||||||
|
margin-left: 0;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
height:28px;
|
height:28px;
|
||||||
}
|
}
|
||||||
.btn-toolbar:last-child {
|
.btn-toolbar:first-child ,
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
.btn-toolbar:only-child {
|
.btn-toolbar:only-child {
|
||||||
margin-left: @spacing-three-quarters;
|
margin-left: @spacing-three-quarters;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue