mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-02-27 09:36:28 +08:00
feat(keybindings): Show all keybindings in prefs
This commit is contained in:
parent
465d60489f
commit
092956b379
5 changed files with 149 additions and 45 deletions
|
@ -5,14 +5,63 @@ fs = require 'fs'
|
|||
{RetinaImg, Flexbox} = require 'nylas-component-kit'
|
||||
|
||||
DisplayedKeybindings = [
|
||||
['application:new-message', 'New Message'],
|
||||
['application:reply', 'Reply'],
|
||||
['application:reply-all', 'Reply All'],
|
||||
['application:forward', 'Forward'],
|
||||
['application:focus-search', 'Search'],
|
||||
['application:change-category', 'Change Folder / Labels'],
|
||||
['core:select-item', 'Select Focused Item'],
|
||||
['application:star-item', 'Star Focused Item'],
|
||||
{
|
||||
title: 'Application',
|
||||
items: [
|
||||
['application:new-message', 'New Message'],
|
||||
['application:focus-search', 'Search'],
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Actions',
|
||||
items: [
|
||||
['application:reply', 'Reply'],
|
||||
['application:reply-all', 'Reply All'],
|
||||
['application:forward', 'Forward'],
|
||||
['application:archive-item', 'Archive'],
|
||||
['application:delete-item', 'Trash'],
|
||||
['core:remove-from-view', 'Remove from view'],
|
||||
['application:star-item', 'Star'],
|
||||
['application:change-category', 'Change Folder / Labels'],
|
||||
['application:mark-as-read', 'Mark as read'],
|
||||
['application:mark-as-unread', 'Mark as unread'],
|
||||
['application:mark-important', 'Mark as important (Gmail)'],
|
||||
['application:mark-unimportant', 'Mark as unimportant (Gmail)'],
|
||||
['application:remove-and-previous', 'Remove from view and previous'],
|
||||
['application:remove-and-next', 'Remove from view and next'],
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Navigation',
|
||||
items: [
|
||||
['application:pop-sheet', 'Return to conversation list'],
|
||||
['core:focus-item', 'Open selected conversation'],
|
||||
['core:previous-item', 'Move to newer conversation'],
|
||||
['core:next-item', 'Move to older conversation'],
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Selection',
|
||||
items: [
|
||||
['core:select-item', 'Select conversation'],
|
||||
['multiselect-list:select-all', 'Select all conversations'],
|
||||
['multiselect-list:deselect-all', 'Deselect all conversations'],
|
||||
['thread-list:select-read', 'Select all read conversations'],
|
||||
['thread-list:select-unread', 'Select all unread conversations'],
|
||||
['thread-list:select-starred', 'Select all starred conversations'],
|
||||
['thread-list:select-unstarred', 'Select all unstarred conversations'],
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Jumping',
|
||||
items: [
|
||||
['navigation:go-to-inbox', 'Go to "Inbox"'],
|
||||
['navigation:go-to-starred', 'Go to "Starred"'],
|
||||
['navigation:go-to-sent', 'Go to "Sent Mail"'],
|
||||
['navigation:go-to-drafts', 'Go to "Drafts"'],
|
||||
['navigation:go-to-all', 'Go to "All Mail"'],
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
class PreferencesKeymaps extends React.Component
|
||||
|
@ -43,17 +92,18 @@ class PreferencesKeymaps extends React.Component
|
|||
|
||||
_getStateFromKeymaps: =>
|
||||
bindings = {}
|
||||
for [command, label] in DisplayedKeybindings
|
||||
bindings[command] = NylasEnv.keymaps.findKeyBindings(command: command, target: document.body) || []
|
||||
for section in DisplayedKeybindings
|
||||
for [command, label] in section.items
|
||||
bindings[command] = NylasEnv.keymaps.findKeyBindings(command: command, target: document.body) || []
|
||||
bindings
|
||||
|
||||
render: =>
|
||||
<div className="container-keymaps">
|
||||
<section>
|
||||
<h2>Shortcuts</h2>
|
||||
<Flexbox className="shortcut shortcut-select">
|
||||
<div className="shortcut-name">Keyboard shortcut set:</div>
|
||||
<div className="shortcut-value">
|
||||
<Flexbox className="shortcut-presets">
|
||||
<div className="col-left">Keyboard shortcut set:</div>
|
||||
<div className="col-right">
|
||||
<select
|
||||
style={margin:0}
|
||||
value={@props.config.get('core.keymapTemplate')}
|
||||
|
@ -64,7 +114,9 @@ class PreferencesKeymaps extends React.Component
|
|||
</select>
|
||||
</div>
|
||||
</Flexbox>
|
||||
{@_renderBindings()}
|
||||
{
|
||||
DisplayedKeybindings.map(@_renderBindingsSection)
|
||||
}
|
||||
</section>
|
||||
<section>
|
||||
<h2>Customization</h2>
|
||||
|
@ -73,32 +125,60 @@ class PreferencesKeymaps extends React.Component
|
|||
</section>
|
||||
</div>
|
||||
|
||||
_renderBindingsSection: (section) =>
|
||||
<section>
|
||||
<div className="shortcut-section-title">{section.title}</div>
|
||||
{
|
||||
section.items.map(@_renderBindingFor)
|
||||
}
|
||||
</section>
|
||||
|
||||
_renderBindingFor: ([command, label]) =>
|
||||
descriptions = []
|
||||
if @state.bindings[command]
|
||||
for binding in @state.bindings[command]
|
||||
descriptions.push(@_formatKeystrokes(binding.keystrokes))
|
||||
descriptions.push(binding.keystrokes)
|
||||
|
||||
if descriptions.length is 0
|
||||
value = 'None'
|
||||
else
|
||||
value = _.uniq(descriptions).join(', ')
|
||||
value = _.uniq(descriptions).map(@_renderKeystrokes)
|
||||
|
||||
<Flexbox className="shortcut" key={command}>
|
||||
<div className="shortcut-name">{label}</div>
|
||||
<div className="shortcut-value">{value}</div>
|
||||
<div className="col-left shortcut-name">{label}</div>
|
||||
<div className="col-right">{value}</div>
|
||||
</Flexbox>
|
||||
|
||||
_renderBindings: =>
|
||||
DisplayedKeybindings.map(@_renderBindingFor)
|
||||
_renderKeystrokes: (keystrokes) =>
|
||||
elements = []
|
||||
keystrokes = keystrokes.split(' ')
|
||||
|
||||
_formatKeystrokes: (keystrokes) ->
|
||||
for keystroke, idx in keystrokes
|
||||
elements.push <span>{@_formatKeystrokes(keystroke)}</span>
|
||||
elements.push <span className="then"> then </span> unless idx is keystrokes.length - 1
|
||||
|
||||
<span className="shortcut-value">{elements}</span>
|
||||
|
||||
_formatKeystrokes: (original) =>
|
||||
if process.platform is 'win32'
|
||||
# On Windows, display cmd-shift-c
|
||||
return keystrokes
|
||||
return original
|
||||
|
||||
else
|
||||
# On Mac and Linux, display ⌘⇧C
|
||||
return keystrokes.replace(/-/gi,'').replace(/cmd/gi, '⌘').replace(/alt/gi, '⌥').replace(/shift/gi, '⇧').replace(/ctrl/gi, '^').toUpperCase()
|
||||
# Replace "cmd" => ⌘, etc.
|
||||
modifiers = [[/-(?!$)/gi,''], [/cmd/gi, '⌘'], [/alt/gi, '⌥'], [/shift/gi, '⇧'], [/ctrl/gi, '^']]
|
||||
clean = original
|
||||
for [regexp, char] in modifiers
|
||||
clean = clean.replace(regexp, char)
|
||||
|
||||
# ⌘⇧c => ⌘⇧C
|
||||
if clean isnt original
|
||||
clean = clean.toUpperCase()
|
||||
|
||||
# backspace => Backspace
|
||||
if original.length > 1 and clean is original
|
||||
clean = clean[0].toUpperCase() + clean[1..-1]
|
||||
return clean
|
||||
|
||||
_onShowUserKeymaps: =>
|
||||
keymapsFile = NylasEnv.keymaps.getUserKeymapPath()
|
||||
|
|
|
@ -140,24 +140,49 @@
|
|||
.container-keymaps {
|
||||
max-width: 450px;
|
||||
|
||||
.col-left {
|
||||
text-align: right;
|
||||
flex: 1;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.col-right {
|
||||
text-align: left;
|
||||
flex: 1;
|
||||
select {
|
||||
width: 75%;
|
||||
}
|
||||
}
|
||||
|
||||
.shortcut-presets {
|
||||
padding: 5px 0 20px 0;
|
||||
}
|
||||
|
||||
.shortcut-section-title {
|
||||
border-bottom:1px solid @border-color-divider;
|
||||
margin: @padding-large-vertical * 1.5 0;
|
||||
}
|
||||
|
||||
.shortcut {
|
||||
padding: 3px 0;
|
||||
&.shortcut-select {
|
||||
padding: 5px 0 20px 0;
|
||||
select {
|
||||
width: 75%;
|
||||
}
|
||||
}
|
||||
|
||||
.shortcut-name {
|
||||
text-align: right;
|
||||
flex: 1;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
color: @text-color-very-subtle;
|
||||
.shortcut-value {
|
||||
text-align: left;
|
||||
flex: 1;
|
||||
font-family: monospace;
|
||||
font-weight: 600;
|
||||
color: @text-color;
|
||||
.then {
|
||||
font-family: @font-family-base;
|
||||
color: @text-color-very-subtle;
|
||||
font-weight: 400;
|
||||
font-size: 0.9em;
|
||||
padding-left:3px;
|
||||
padding-right:3px;
|
||||
}
|
||||
&:after {
|
||||
content: ", "
|
||||
}
|
||||
&:last-child:after {
|
||||
content: "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
'o': 'core:focus-item'
|
||||
'p': 'message-list:previous-message'
|
||||
'n': 'message-list:next-message'
|
||||
'`': 'thread-list:next-inbox'
|
||||
'~': 'thread-list:previous-inbox'
|
||||
|
||||
### Application ###
|
||||
'c': 'application:new-message'
|
||||
|
@ -56,8 +54,6 @@
|
|||
'f': 'application:forward'
|
||||
'F': 'application:forward-new-window'
|
||||
|
||||
'N': 'application:update-conversation'
|
||||
|
||||
']': 'application:remove-and-previous'
|
||||
'}': 'application:remove-and-previous'
|
||||
'[': 'application:remove-and-next'
|
||||
|
|
|
@ -28,7 +28,10 @@ h2 {
|
|||
font-size: @font-size-h2;
|
||||
font-weight: @font-weight-blond;
|
||||
}
|
||||
h3 { font-size: @font-size-h3; }
|
||||
h3 {
|
||||
font-size: @font-size-h3;
|
||||
font-weight: @font-weight-blond;
|
||||
}
|
||||
h4 { font-size: @font-size-h4; }
|
||||
h5 { font-size: @font-size-h5; }
|
||||
h6 { font-size: @font-size-h6; }
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
|
||||
@font-size-h1: @font-size-base * 1.6; // 24px
|
||||
@font-size-h2: @font-size-base * 1.6; // 24px
|
||||
@font-size-h3: @font-size-base * 1.7; // 24px
|
||||
@font-size-h3: @font-size-base * 1.4; // 24px
|
||||
@font-size-h4: @font-size-base * 1.25; // 18px
|
||||
@font-size-h5: @font-size-base;
|
||||
@font-size-h6: @font-size-base * 0.85; // 12px
|
||||
|
|
Loading…
Reference in a new issue