feat(composer): new composer and button styles
Summary: initial styling of image attachments more styles for composer overflow style composer toolbar toolbar styling Fixes to inline composer Test Plan: edgehill --test Reviewers: bengotow Reviewed By: bengotow Differential Revision: https://phab.nylas.com/D1647
|
@ -30,7 +30,7 @@ class AttachmentComponent extends React.Component
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span className="attachment-file-actions">
|
<span className="attachment-file-actions">
|
||||||
{@_fileActions()}
|
{@_renderFileActions()}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span className="attachment-file-and-name" onClick={@_onClickView}>
|
<span className="attachment-file-and-name" onClick={@_onClickView}>
|
||||||
|
@ -44,18 +44,18 @@ class AttachmentComponent extends React.Component
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
_fileActions: =>
|
_renderFileActions: =>
|
||||||
if @props.removable
|
if @props.removable
|
||||||
<div className="attachment-icon" onClick={@_onClickRemove}>
|
<div className="attachment-icon" onClick={@_onClickRemove}>
|
||||||
<RetinaImg className="remove-icon" name="remove-attachment.png"/>
|
{@_renderRemoveIcon()}
|
||||||
</div>
|
</div>
|
||||||
else if @_isDownloading() and @_canAbortDownload()
|
else if @_isDownloading() and @_canAbortDownload()
|
||||||
<div className="attachment-icon" onClick={@_onClickAbort}>
|
<div className="attachment-icon" onClick={@_onClickAbort}>
|
||||||
<RetinaImg className="remove-icon" name="remove-attachment.png"/>
|
{@_renderRemoveIcon()}
|
||||||
</div>
|
</div>
|
||||||
else
|
else
|
||||||
<div className="attachment-icon" onClick={@_onClickDownload}>
|
<div className="attachment-icon" onClick={@_onClickDownload}>
|
||||||
<i className="fa fa-download" style={position: "relative", top: "2px"}></i>
|
{@_renderDownloadButton()}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
_downloadProgressStyle: =>
|
_downloadProgressStyle: =>
|
||||||
|
@ -68,6 +68,12 @@ class AttachmentComponent extends React.Component
|
||||||
|
|
||||||
_canAbortDownload: -> true
|
_canAbortDownload: -> true
|
||||||
|
|
||||||
|
_renderRemoveIcon: ->
|
||||||
|
<RetinaImg className="remove-icon" name="remove-attachment.png"/>
|
||||||
|
|
||||||
|
_renderDownloadButton: ->
|
||||||
|
<RetinaImg className="download-icon" name="icon-attachment-download.png"/>
|
||||||
|
|
||||||
_onClickView: => Actions.fetchAndOpenFile(@props.file) if @_canClickToView()
|
_onClickView: => Actions.fetchAndOpenFile(@props.file) if @_canClickToView()
|
||||||
|
|
||||||
_onClickDownload: => Actions.fetchAndSaveFile(@props.file)
|
_onClickDownload: => Actions.fetchAndSaveFile(@props.file)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
path = require 'path'
|
path = require 'path'
|
||||||
React = require 'react'
|
React = require 'react'
|
||||||
AttachmentComponent = require './attachment-component'
|
AttachmentComponent = require './attachment-component'
|
||||||
{Spinner, DraggableImg} = require 'nylas-component-kit'
|
{RetinaImg, Spinner, DraggableImg} = require 'nylas-component-kit'
|
||||||
|
|
||||||
class ImageAttachmentComponent extends AttachmentComponent
|
class ImageAttachmentComponent extends AttachmentComponent
|
||||||
@displayName: 'ImageAttachmentComponent'
|
@displayName: 'ImageAttachmentComponent'
|
||||||
|
@ -13,11 +13,13 @@ class ImageAttachmentComponent extends AttachmentComponent
|
||||||
<span className="attachment-download-progress" style={@_downloadProgressStyle()}></span>
|
<span className="attachment-download-progress" style={@_downloadProgressStyle()}></span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span className="attachment-file-actions">
|
<div className="attachment-file-actions">
|
||||||
{@_fileActions()}
|
{@_fileActions()}
|
||||||
</span>
|
</div>
|
||||||
|
|
||||||
<div className="attachment-preview" onClick={@_onClickView}>
|
<div className="attachment-preview" onClick={@_onClickView}>
|
||||||
|
<div className="attachment-name-bg"></div>
|
||||||
|
<div className="attachment-name">{@props.file.filename}</div>
|
||||||
{@_imgOrLoader()}
|
{@_imgOrLoader()}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -25,6 +27,12 @@ class ImageAttachmentComponent extends AttachmentComponent
|
||||||
|
|
||||||
_canAbortDownload: -> false
|
_canAbortDownload: -> false
|
||||||
|
|
||||||
|
_renderRemoveIcon: ->
|
||||||
|
<RetinaImg className="image-remove-icon" name="image-cancel-button.png"/>
|
||||||
|
|
||||||
|
_renderDownloadButton: ->
|
||||||
|
<RetinaImg className="image-download-icon" name="image-download-button.png"/>
|
||||||
|
|
||||||
_imgOrLoader: ->
|
_imgOrLoader: ->
|
||||||
if @props.download
|
if @props.download
|
||||||
if @props.download.percent <= 5
|
if @props.download.percent <= 5
|
||||||
|
|
|
@ -16,6 +16,14 @@
|
||||||
width: calc(~"50% - 7.5px");
|
width: calc(~"50% - 7.5px");
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|
||||||
|
&.non-image-attachment {
|
||||||
|
width: calc(~"50% - 23px");
|
||||||
|
margin-left: 15px;
|
||||||
|
&:nth-child(even) {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.file-upload {
|
&.file-upload {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 13px @spacing-standard 13px @spacing-standard;
|
padding: 13px @spacing-standard 13px @spacing-standard;
|
||||||
|
@ -53,6 +61,7 @@
|
||||||
.attachment-file-name {
|
.attachment-file-name {
|
||||||
font-weight: @font-weight-medium;
|
font-weight: @font-weight-medium;
|
||||||
}
|
}
|
||||||
|
margin-left: 15px;
|
||||||
.attachment-file-and-name {
|
.attachment-file-and-name {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
@ -121,7 +130,7 @@
|
||||||
|
|
||||||
.image-attachment-file-wrap, .image-file-upload {
|
.image-attachment-file-wrap, .image-file-upload {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: @spacing-standard 0;
|
margin: 0 0 8px 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
.attachment-download-progress,
|
.attachment-download-progress,
|
||||||
|
@ -132,30 +141,56 @@
|
||||||
bottom: -2px;
|
bottom: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.attachment-file-actions {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
.attachment-file-actions {
|
.attachment-file-actions, .attachment-name-bg, .attachment-name {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.attachment-file-actions {
|
.attachment-file-actions, .attachment-name-bg, .attachment-name {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.attachment-icon {
|
.attachment-icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
right: 0;
|
right: -8px;
|
||||||
top: 0;
|
top: -8px;
|
||||||
background: @white;
|
|
||||||
width: 26px;
|
width: 26px;
|
||||||
border-radius: 0 0 0 3px;
|
border-radius: 0 0 0 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.attachment-preview img {
|
.attachment-preview {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
max-width: 100%;
|
|
||||||
background: @background-secondary;
|
.attachment-name-bg {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 2;
|
||||||
|
width: 100%;
|
||||||
|
background: linear-gradient(to top, rgba(0,0,0,0.75) 0%,rgba(0,0,0,0) 23%)
|
||||||
|
}
|
||||||
|
.attachment-name {
|
||||||
|
color: @white;
|
||||||
|
left: 15px;
|
||||||
|
bottom: 13px;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
max-width: 100%;
|
||||||
|
background: @background-secondary;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -184,7 +184,9 @@ class ComposerView extends React.Component
|
||||||
|
|
||||||
{@_renderFields()}
|
{@_renderFields()}
|
||||||
|
|
||||||
<div className="compose-body">
|
<div className="compose-body"
|
||||||
|
ref="composeBody"
|
||||||
|
onClick={@_onClickComposeBody}>
|
||||||
<ContenteditableComponent ref="contentBody"
|
<ContenteditableComponent ref="contentBody"
|
||||||
html={@state.body}
|
html={@state.body}
|
||||||
onChange={@_onChangeBody}
|
onChange={@_onChangeBody}
|
||||||
|
@ -347,18 +349,18 @@ class ComposerView extends React.Component
|
||||||
|
|
||||||
<button className="btn btn-toolbar btn-trash" style={order: 100}
|
<button className="btn btn-toolbar btn-trash" style={order: 100}
|
||||||
data-tooltip="Delete draft"
|
data-tooltip="Delete draft"
|
||||||
onClick={@_destroyDraft}><RetinaImg name="toolbar-trash.png" mode={RetinaImg.Mode.ContentIsMask} /></button>
|
onClick={@_destroyDraft}><RetinaImg name="icon-composer-trash.png" mode={RetinaImg.Mode.ContentIsMask} /></button>
|
||||||
|
|
||||||
<button className="btn btn-toolbar btn-attach" style={order: 50}
|
<button className="btn btn-toolbar btn-attach" style={order: 50}
|
||||||
data-tooltip="Attach file"
|
data-tooltip="Attach file"
|
||||||
onClick={@_attachFile}><RetinaImg name="toolbar-attach.png" mode={RetinaImg.Mode.ContentIsMask} /></button>
|
onClick={@_attachFile}><RetinaImg name="icon-composer-attachment.png" mode={RetinaImg.Mode.ContentIsMask} /></button>
|
||||||
|
|
||||||
<div style={order: 0, flex: 1} />
|
<div style={order: 0, flex: 1} />
|
||||||
|
|
||||||
<button className="btn btn-toolbar btn-emphasis btn-send" style={order: -100}
|
<button className="btn btn-toolbar btn-emphasis btn-text btn-send" style={order: -100}
|
||||||
data-tooltip="Send message"
|
data-tooltip="Send message"
|
||||||
ref="sendButton"
|
ref="sendButton"
|
||||||
onClick={@_sendDraft}><RetinaImg name="toolbar-send.png" mode={RetinaImg.Mode.ContentIsMask} /> Send</button>
|
onClick={@_sendDraft}><RetinaImg name="icon-composer-send.png" mode={RetinaImg.Mode.ContentIsMask} /><span className="text">Send</span></button>
|
||||||
|
|
||||||
</InjectedComponentSet>
|
</InjectedComponentSet>
|
||||||
|
|
||||||
|
@ -386,6 +388,12 @@ class ComposerView extends React.Component
|
||||||
draft = @_proxy.draft()
|
draft = @_proxy.draft()
|
||||||
Utils.isForwardedMessage(draft)
|
Utils.isForwardedMessage(draft)
|
||||||
|
|
||||||
|
# This lets us click outside of the `contenteditable`'s `contentBody`
|
||||||
|
# and still focus on the contenteditable
|
||||||
|
_onClickComposeBody: (event) =>
|
||||||
|
if event.target is React.findDOMNode(@refs.composeBody)
|
||||||
|
@focus("contentBody")
|
||||||
|
|
||||||
_onDraftChanged: =>
|
_onDraftChanged: =>
|
||||||
return unless @_proxy
|
return unless @_proxy
|
||||||
draft = @_proxy.draft()
|
draft = @_proxy.draft()
|
||||||
|
|
|
@ -11,13 +11,15 @@ class ImageFileUpload extends FileUpload
|
||||||
|
|
||||||
render: =>
|
render: =>
|
||||||
<div className="image-file-upload #{@props.uploadData.state}">
|
<div className="image-file-upload #{@props.uploadData.state}">
|
||||||
<span className="attachment-file-actions">
|
<div className="attachment-file-actions">
|
||||||
<div className="attachment-icon" onClick={@_onClickRemove}>
|
<div className="attachment-icon" onClick={@_onClickRemove}>
|
||||||
<RetinaImg className="remove-icon" name="remove-attachment.png"/>
|
<RetinaImg className="image-remove-icon" name="image-cancel-button.png"/>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</div>
|
||||||
|
|
||||||
<div className="attachment-preview" >
|
<div className="attachment-preview" >
|
||||||
|
<div className="attachment-name-bg"></div>
|
||||||
|
<div className="attachment-name">{@props.uploadData.fileName}</div>
|
||||||
<DraggableImg src={@props.uploadData.filePath} />
|
<DraggableImg src={@props.uploadData.filePath} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -55,9 +55,10 @@ module.exports =
|
||||||
ComponentRegistry.register ComposeButton,
|
ComponentRegistry.register ComposeButton,
|
||||||
location: WorkspaceStore.Location.RootSidebar.Toolbar
|
location: WorkspaceStore.Location.RootSidebar.Toolbar
|
||||||
else
|
else
|
||||||
atom.getCurrentWindow().setMinimumSize(600, 400)
|
atom.getCurrentWindow().setMinimumSize(480, 400)
|
||||||
WorkspaceStore.defineSheet 'Main', {root: true},
|
WorkspaceStore.defineSheet 'Main', {root: true},
|
||||||
list: ['Center']
|
popout: ['Center']
|
||||||
|
|
||||||
ComponentRegistry.register ComposerWithWindowProps,
|
ComponentRegistry.register ComposerWithWindowProps,
|
||||||
location: WorkspaceStore.Location.Center
|
location: WorkspaceStore.Location.Center
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
flex-direction:row;
|
flex-direction:row;
|
||||||
max-width: @compose-width;
|
max-width: @compose-width;
|
||||||
padding: @spacing-standard (@spacing-standard + @spacing-standard / 2) @spacing-standard*1.1;
|
padding: @spacing-standard;
|
||||||
|
|
||||||
> * {
|
> * {
|
||||||
margin-left: @spacing-standard / 2;
|
margin-left: @spacing-standard / 2;
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
max-width: @compose-width;
|
max-width: @compose-width;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
margin-top: @spacing-standard;
|
margin-top: @spacing-standard;
|
||||||
padding: 0 @spacing-standard;
|
padding: 0;
|
||||||
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -79,7 +79,7 @@
|
||||||
.composer-participant-actions {
|
.composer-participant-actions {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 900;
|
z-index: 900;
|
||||||
right: @spacing-double;
|
right: 23px;
|
||||||
.header-action {
|
.header-action {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 1em;
|
top: 1em;
|
||||||
|
@ -104,8 +104,8 @@
|
||||||
.compose-subject-wrap {
|
.compose-subject-wrap {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
padding: 5px @spacing-standard 0 0;
|
padding: 11px @spacing-standard 11px 0;
|
||||||
margin: 0 @spacing-standard;
|
margin: 0 23px;
|
||||||
border-bottom: 1px solid @border-color-divider;
|
border-bottom: 1px solid @border-color-divider;
|
||||||
flex-shrink:0;
|
flex-shrink:0;
|
||||||
|
|
||||||
|
@ -119,8 +119,8 @@
|
||||||
input.compose-field {
|
input.compose-field {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: calc(~"100% - 61px");
|
width: calc(~"100% - 61px");
|
||||||
padding: 6px 0 2px 0;
|
padding: 0;
|
||||||
margin: 0 0 5px 5px;
|
margin: 0 0 0 5px;
|
||||||
min-width: 5em;
|
min-width: 5em;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border: none;
|
border: none;
|
||||||
|
@ -139,10 +139,11 @@
|
||||||
cursor: text;
|
cursor: text;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
padding: 0 8px;
|
||||||
|
|
||||||
.quoted-text-control {
|
.quoted-text-control {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: -25px;
|
bottom: 10px;
|
||||||
left: 15px;
|
left: 15px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
@ -152,11 +153,12 @@
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
min-height: @compose-min-height;
|
min-height: @compose-min-height;
|
||||||
padding: @spacing-standard;
|
padding: @spacing-standard;
|
||||||
padding-top: @spacing-standard;
|
padding-top: 20px;
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
.contenteditable-container {
|
.contenteditable-container {
|
||||||
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
@ -171,7 +173,7 @@
|
||||||
|
|
||||||
// TODO FIXME DRY From stylesheets/message-list.less
|
// TODO FIXME DRY From stylesheets/message-list.less
|
||||||
.attachments-area {
|
.attachments-area {
|
||||||
padding: 0 15px 0 15px;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.token {
|
.token {
|
||||||
|
@ -182,25 +184,7 @@
|
||||||
color: @text-color-inverse-very-subtle;
|
color: @text-color-inverse-very-subtle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// &:hover {
|
|
||||||
// background: transparent;
|
|
||||||
// }
|
|
||||||
// &.selected,
|
|
||||||
// &.dragging {
|
|
||||||
// background: transparent;
|
|
||||||
// color: @text-color;
|
|
||||||
//
|
|
||||||
// .action { color: @text-color-subtle; }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// .btn.btn-send {
|
|
||||||
// font-weight: @font-weight-semi-bold;
|
|
||||||
// color: @accent-primary-dark;
|
|
||||||
// border-top: 1px solid fade(@accent-primary, 39%);
|
|
||||||
// border-right: 1px solid fade(@accent-primary, 39%);
|
|
||||||
// border-left: 1px solid fade(@accent-primary, 39%);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
body.is-blurred .composer-inner-wrap .tokenizing-field .token {
|
body.is-blurred .composer-inner-wrap .tokenizing-field .token {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
@ -223,12 +207,15 @@ body.is-blurred .composer-inner-wrap .tokenizing-field .token {
|
||||||
border-top:1px solid @border-color-divider;
|
border-top:1px solid @border-color-divider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.composer-action-bar-content {
|
||||||
|
padding: 8px 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
.compose-body {
|
.compose-body {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.contenteditable-container {
|
.contenteditable-container {
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -241,6 +228,12 @@ body.is-blurred .composer-inner-wrap .tokenizing-field .token {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.compose-body {
|
||||||
|
div[contenteditable] {
|
||||||
|
min-height: @line-height-computed;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overrides for the composer in a message-list
|
// Overrides for the composer in a message-list
|
||||||
|
@ -262,6 +255,7 @@ body.is-blurred .composer-inner-wrap .tokenizing-field .token {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
padding: 5px @spacing-standard 0 @spacing-standard;
|
padding: 5px @spacing-standard 0 @spacing-standard;
|
||||||
|
margin: 0 8px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
.participant {
|
.participant {
|
||||||
|
|
|
@ -22,9 +22,10 @@ class TemplatePicker extends React.Component
|
||||||
@unsubscribe() if @unsubscribe
|
@unsubscribe() if @unsubscribe
|
||||||
|
|
||||||
render: =>
|
render: =>
|
||||||
button = <button className="btn btn-toolbar">
|
button = <button className="btn btn-toolbar" style={padding: "2px 9px"}>
|
||||||
<RetinaImg name="toolbar-templates.png" mode={RetinaImg.Mode.ContentIsMask}/>
|
<RetinaImg name="icon-composer-templates.png" mode={RetinaImg.Mode.ContentIsMask}/>
|
||||||
<RetinaImg name="toolbar-chevron.png" mode={RetinaImg.Mode.ContentIsMask}/>
|
|
||||||
|
<RetinaImg name="icon-composer-dropdown.png" mode={RetinaImg.Mode.ContentIsMask}/>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
headerComponents = [
|
headerComponents = [
|
||||||
|
|
|
@ -109,6 +109,7 @@ class RetinaImg extends React.Component
|
||||||
|
|
||||||
if @props.mode is Mode.ContentIsMask
|
if @props.mode is Mode.ContentIsMask
|
||||||
style.WebkitMaskImage = "url('#{path}')"
|
style.WebkitMaskImage = "url('#{path}')"
|
||||||
|
style.WebkitMaskRepeat = "no-repeat"
|
||||||
style.objectPosition = "10000px"
|
style.objectPosition = "10000px"
|
||||||
className += " content-mask"
|
className += " content-mask"
|
||||||
else if @props.mode is Mode.ContentDark
|
else if @props.mode is Mode.ContentDark
|
||||||
|
|
|
@ -327,8 +327,11 @@ class DraftStore
|
||||||
draft: true
|
draft: true
|
||||||
pristine: true
|
pristine: true
|
||||||
namespaceId: namespace.id
|
namespaceId: namespace.id
|
||||||
|
|
||||||
DatabaseStore.persistModel(draft).then =>
|
DatabaseStore.persistModel(draft).then =>
|
||||||
DatabaseStore.localIdForModel(draft).then(@_onPopoutDraftLocalId)
|
DatabaseStore.localIdForModel(draft).then (draftLocalId, options={}) =>
|
||||||
|
options.newDraft = true
|
||||||
|
@_onPopoutDraftLocalId(draftLocalId, options)
|
||||||
|
|
||||||
_onPopoutDraftLocalId: (draftLocalId, options = {}) =>
|
_onPopoutDraftLocalId: (draftLocalId, options = {}) =>
|
||||||
return unless NamespaceStore.current()
|
return unless NamespaceStore.current()
|
||||||
|
@ -337,9 +340,11 @@ class DraftStore
|
||||||
if @_draftSessions[draftLocalId]
|
if @_draftSessions[draftLocalId]
|
||||||
save = @_draftSessions[draftLocalId].changes.commit()
|
save = @_draftSessions[draftLocalId].changes.commit()
|
||||||
|
|
||||||
|
title = if options.newDraft then "New Message" else "Message"
|
||||||
|
|
||||||
save.then =>
|
save.then =>
|
||||||
atom.newWindow
|
atom.newWindow
|
||||||
title: "Message"
|
title: title
|
||||||
windowType: "composer"
|
windowType: "composer"
|
||||||
windowProps: _.extend(options, {draftLocalId})
|
windowProps: _.extend(options, {draftLocalId})
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ class SheetContainer extends React.Component
|
||||||
|
|
||||||
sheetElements = @_sheetElements()
|
sheetElements = @_sheetElements()
|
||||||
|
|
||||||
<Flexbox direction="column">
|
<Flexbox direction="column" className="layout-mode-#{@state.mode}">
|
||||||
{@_toolbarContainerElement()}
|
{@_toolbarContainerElement()}
|
||||||
|
|
||||||
<div name="Header" style={order:1, zIndex: 2}>
|
<div name="Header" style={order:1, zIndex: 2}>
|
||||||
|
@ -96,6 +96,7 @@ class SheetContainer extends React.Component
|
||||||
|
|
||||||
_getStateFromStores: =>
|
_getStateFromStores: =>
|
||||||
stack: WorkspaceStore.sheetStack()
|
stack: WorkspaceStore.sheetStack()
|
||||||
|
mode: WorkspaceStore.layoutMode()
|
||||||
|
|
||||||
|
|
||||||
module.exports = SheetContainer
|
module.exports = SheetContainer
|
||||||
|
|
|
@ -17,6 +17,21 @@ class ToolbarSpacer extends React.Component
|
||||||
render: =>
|
render: =>
|
||||||
<div className="item-spacer" style={flex: 1, order:@props.order ? 0}></div>
|
<div className="item-spacer" style={flex: 1, order:@props.order ? 0}></div>
|
||||||
|
|
||||||
|
class WindowTitle extends React.Component
|
||||||
|
@displayName: "WindowTitle"
|
||||||
|
|
||||||
|
constructor: (@props) ->
|
||||||
|
@state = atom.getLoadSettings()
|
||||||
|
|
||||||
|
componentDidMount: ->
|
||||||
|
@unlisten = atom.onWindowPropsReceived (windowProps) =>
|
||||||
|
@setState atom.getLoadSettings()
|
||||||
|
|
||||||
|
componentWillUnmount: -> @unlisten()
|
||||||
|
|
||||||
|
render: ->
|
||||||
|
<div className="window-title">{@state.title}</div>
|
||||||
|
|
||||||
class ToolbarBack extends React.Component
|
class ToolbarBack extends React.Component
|
||||||
@displayName: 'ToolbarBack'
|
@displayName: 'ToolbarBack'
|
||||||
render: =>
|
render: =>
|
||||||
|
@ -154,6 +169,9 @@ class Toolbar extends React.Component
|
||||||
entries = ComponentRegistry.findComponentsMatching({location: loc.Toolbar.Right, mode: state.mode})
|
entries = ComponentRegistry.findComponentsMatching({location: loc.Toolbar.Right, mode: state.mode})
|
||||||
state.columns[state.columns.length - 1]?.push(entries...)
|
state.columns[state.columns.length - 1]?.push(entries...)
|
||||||
|
|
||||||
|
if state.mode is "popout"
|
||||||
|
state.columns[0]?.push(WindowTitle)
|
||||||
|
|
||||||
state
|
state
|
||||||
|
|
||||||
module.exports = Toolbar
|
module.exports = Toolbar
|
||||||
|
|
|
@ -10,11 +10,12 @@ button, html input[type="button"] {
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
padding: 0.33em 1em;
|
padding: 0.33em 1em;
|
||||||
border:1px solid rgba(0,0,0,0.18);
|
border:1px solid rgba(0,0,0,0.15);
|
||||||
border-radius: @border-radius-base;
|
border-radius: @border-radius-base;
|
||||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.10);
|
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
|
||||||
cursor: default;
|
cursor: default;
|
||||||
display:inline-block;
|
display:inline-block;
|
||||||
|
background: linear-gradient(to top, rgba(241,241,241,0.75) 0%, rgba(253,253,253,0.75) 100%);
|
||||||
|
|
||||||
height: auto;
|
height: auto;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
|
@ -55,12 +56,27 @@ button, html input[type="button"] {
|
||||||
}
|
}
|
||||||
|
|
||||||
&.btn-emphasis {
|
&.btn-emphasis {
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(lighten(@btn-emphasis-bg-color,10%)), to(@btn-emphasis-bg-color));
|
position: relative;
|
||||||
border:1px solid darken(@btn-emphasis-bg-color, 5%);
|
|
||||||
color: @btn-emphasis-text-color;
|
color: @btn-emphasis-text-color;
|
||||||
font-weight: @font-weight-medium;
|
font-weight: @font-weight-medium;
|
||||||
|
|
||||||
img.content-mask { background-color:@btn-emphasis-text-color; }
|
img.content-mask { background-color:@btn-emphasis-text-color; }
|
||||||
|
|
||||||
|
background: linear-gradient(to bottom, #6bb1f9 0%, #0a80ff 100%);
|
||||||
|
|
||||||
|
border: 0;
|
||||||
|
&:before {
|
||||||
|
content: ' ';
|
||||||
|
width: calc(~"100% + 2px");
|
||||||
|
height: calc(~"100% + 2px");
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 0;
|
||||||
|
top: -1px;
|
||||||
|
left: -1px;
|
||||||
|
position: absolute;
|
||||||
|
z-index: -1;
|
||||||
|
background: linear-gradient(to bottom, #4ca2f9 0%, #015cff 100%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.btn-emphasis:active {
|
&.btn-emphasis:active {
|
||||||
|
@ -68,6 +84,16 @@ button, html input[type="button"] {
|
||||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.21);
|
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.21);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.btn-text {
|
||||||
|
font-size: 13px;
|
||||||
|
padding: 2px 14px 2px 7px;
|
||||||
|
.text {
|
||||||
|
position: relative;
|
||||||
|
top: 1px;
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.btn-danger, .btn-destructive {
|
&.btn-danger, .btn-destructive {
|
||||||
color: @btn-danger-text-color;
|
color: @btn-danger-text-color;
|
||||||
background: @btn-danger-bg-color;
|
background: @btn-danger-bg-color;
|
||||||
|
@ -76,7 +102,8 @@ button, html input[type="button"] {
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-toolbar {
|
.btn-toolbar {
|
||||||
min-height:34px;
|
min-height: 24px;
|
||||||
|
padding: 2px 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-gradient {
|
.btn-gradient {
|
||||||
|
|
BIN
static/images/attachments/icon-attachment-download-@1x.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
static/images/attachments/icon-attachment-download-@2x.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
static/images/attachments/image-cancel-button@2x.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
static/images/attachments/image-download-button@2x.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
static/images/composer/icon-composer-attachment@2x.png
Normal file
After Width: | Height: | Size: 660 B |
BIN
static/images/composer/icon-composer-dropdown@2x.png
Normal file
After Width: | Height: | Size: 192 B |
BIN
static/images/composer/icon-composer-send@2x.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
static/images/composer/icon-composer-templates@2x.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
static/images/composer/icon-composer-trash@2x.png
Normal file
After Width: | Height: | Size: 14 KiB |
|
@ -124,6 +124,22 @@ body.is-blurred {
|
||||||
|
|
||||||
.sheet-toolbar-container {
|
.sheet-toolbar-container {
|
||||||
background: @toolbar-background-color;
|
background: @toolbar-background-color;
|
||||||
|
|
||||||
|
&.mode-popout {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mode-popout {
|
||||||
|
.sheet-toolbar {
|
||||||
|
background: @background-primary;
|
||||||
|
height: 35px;
|
||||||
|
min-height: 35px;
|
||||||
|
max-height: 35px;
|
||||||
|
}
|
||||||
|
.toolbar-window-controls {
|
||||||
|
margin-top: 7px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sheet-toolbar {
|
.sheet-toolbar {
|
||||||
|
@ -149,6 +165,20 @@ body.is-blurred {
|
||||||
.item-spacer {
|
.item-spacer {
|
||||||
-webkit-app-region: drag;
|
-webkit-app-region: drag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.item-container {
|
||||||
|
.window-title {
|
||||||
|
flex: 2;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 6px;
|
||||||
|
margin-left: -80px; /* width of ToolbarWindowControls */
|
||||||
|
-webkit-app-region: drag;
|
||||||
|
&:hover {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.item-back {
|
.item-back {
|
||||||
order:-999;
|
order:-999;
|
||||||
padding-top: 5px;
|
padding-top: 5px;
|
||||||
|
@ -265,3 +295,4 @@ body.platform-win32 {
|
||||||
cursor:ew-resize;
|
cursor:ew-resize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|