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:
Ben Gotow 2015-07-23 11:18:42 -07:00
parent 814ed76510
commit 5acbdb0955
11 changed files with 89 additions and 18 deletions

View file

@ -8,6 +8,7 @@ MessageItem = require "./message-item"
DraftStore,
MessageStore,
DatabaseStore,
WorkspaceStore,
ComponentRegistry,
ChangeLabelsTask,
UpdateThreadsTask} = require("nylas-exports")
@ -20,6 +21,34 @@ MessageItem = require "./message-item"
MailLabel,
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
@displayName: 'MessageListScrollTooltip'
@propTypes:
@ -226,7 +255,7 @@ class MessageList extends React.Component
_renderSubject: ->
<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>
{@_renderLabels()}
</div>

View file

@ -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 {
display: flex;
flex-direction: column;
@ -64,7 +77,7 @@
width: calc(~"100% - 12px");
max-width: @message-max-width;
margin: 11px auto 10px auto;
padding: 0 20px;
padding-left: 20px;
-webkit-user-select: text;
line-height: @font-size-large * 1.8;
}
@ -73,12 +86,6 @@
color: @text-color;
margin-right: @spacing-standard;
}
.message-count {
float: right;
font-size: @font-size-small;
color: @text-color-very-subtle;
}
.message-list-headers {
margin: 0 auto;
width: 100%;

View file

@ -21,7 +21,7 @@ class ModeToggle extends React.Component
return <div></div> unless @state.visible
<div className="btn btn-toolbar mode-toggle mode-#{@state.mode}"
style={order:51}
style={order:500}
onClick={@_onToggleMode}>
<RetinaImg
name="toolbar-icon-toggle-pane.png"

View file

@ -1,5 +1,6 @@
React = require 'react'
RetinaImg = require './retina-img'
CategoryStore = require '../flux/stores/category-store'
class MailLabel extends React.Component
@propTypes:
@ -18,7 +19,7 @@ class MailLabel extends React.Component
content = @props.label.displayName
x = null
if @props.onRemove
if @_removable()
classname += ' removable'
content = <span className="inner">{content}</span>
x = <RetinaImg
@ -30,6 +31,8 @@ class MailLabel extends React.Component
<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

View file

@ -175,6 +175,15 @@ class Actions
###
@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

View file

@ -30,6 +30,8 @@ class WorkspaceStore
@listenTo Actions.selectLayoutMode, @_onSelectLayoutMode
@listenTo Actions.setFocus, @_onSetFocus
@listenTo Actions.toggleWorkspaceLocationHidden, @_onToggleLocationHidden
@listenTo Actions.popSheet, @popSheet
@listenTo Actions.searchQueryCommitted, @popToRootSheet
@ -41,6 +43,7 @@ class WorkspaceStore
@Sheet = Sheet = {}
@_preferredLayoutMode = 'list'
@_hiddenLocations = {}
@_sheetStack = []
if atom.isMainWindow()
@ -71,6 +74,16 @@ class WorkspaceStore
@_preferredLayoutMode = mode
@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}) =>
if collection is 'thread'
if @layoutMode() is 'list'
@ -101,22 +114,32 @@ class WorkspaceStore
else
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.
#
topSheet: =>
@_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: =>
@_sheetStack[0]
# Returns an {Array<Sheet>} The stack of sheets
# Public: Returns an {Array<Sheet>} The stack of sheets
#
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
###

View file

@ -182,6 +182,7 @@ class Toolbar extends React.Component
# Add items registered to Regions in the current sheet
if @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})
state.columns.push(entries)

View file

@ -90,6 +90,7 @@ class Sheet extends React.Component
if @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})
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -203,14 +203,12 @@ body.is-blurred {
.btn-toolbar {
margin-top: @spacing-three-quarters;
margin-left: @spacing-three-quarters;
margin-right: @spacing-three-quarters;
margin-left: 0;
flex-shrink: 0;
height:28px;
}
.btn-toolbar:last-child {
margin-left: 0;
}
.btn-toolbar:first-child ,
.btn-toolbar:only-child {
margin-left: @spacing-three-quarters;
}