mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-12-31 04:39:36 +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
814ed76510
commit
5acbdb0955
11 changed files with 89 additions and 18 deletions
|
@ -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>
|
||||
|
|
|
@ -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%;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
###
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 |
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue