mirror of
https://github.com/moparisthebest/mail
synced 2024-11-29 20:32:15 -05:00
Optimized mobile read view
This commit is contained in:
parent
c9c05302d2
commit
c3021a7244
8
src/img/icons/dropup.svg
Normal file
8
src/img/icons/dropup.svg
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="-1.1 262.9 597.5 320.6" enable-background="new -1.1 262.9 597.5 320.6" xml:space="preserve">
|
||||
<path d="M9.2,503.4c-13.7,9.2-13.7,27.5,0,36.6l41.2,36.6c13.7,9.2,32.1,9.2,41.2,0l206.1-174l201.5,174c13.7,9.2,32.1,9.2,41.2,0
|
||||
l45.8-36.6c13.7-9.2,13.7-27.5,0-36.6L316,269.8c-13.7-9.2-32.1-9.2-41.2,0L9.2,503.4z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 693 B |
@ -45,6 +45,7 @@
|
||||
@import "blocks/basics/attachments";
|
||||
@import "blocks/basics/tooltip";
|
||||
@import "blocks/basics/dropdown";
|
||||
@import "blocks/basics/toolbar";
|
||||
@import "blocks/layout/app";
|
||||
@import "blocks/layout/nav";
|
||||
@import "blocks/layout/action-bar";
|
||||
|
@ -299,7 +299,6 @@
|
||||
margin: 0;
|
||||
font-size: $font-size-base;
|
||||
opacity: 0.5;
|
||||
transition: opacity 0.3s;
|
||||
outline: 0;
|
||||
|
||||
&:focus,
|
||||
|
@ -45,4 +45,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__stripped:after {
|
||||
content: "…";
|
||||
}
|
||||
}
|
51
src/sass/blocks/basics/_toolbar.scss
Normal file
51
src/sass/blocks/basics/_toolbar.scss
Normal file
@ -0,0 +1,51 @@
|
||||
.toolbar {
|
||||
&__label {
|
||||
@include scut-truncate;
|
||||
display: block;
|
||||
|
||||
// has to be same as actions
|
||||
box-sizing: content-box;
|
||||
padding: 10px 15px;
|
||||
line-height: 24px;
|
||||
height: 24px;
|
||||
|
||||
font-size: $font-size-bigger;
|
||||
color: $color-text;
|
||||
text-decoration: none;
|
||||
& > svg {
|
||||
display: inline-block;
|
||||
fill: $color-main;
|
||||
vertical-align: baseline;
|
||||
height: 0.8em;
|
||||
width: 0.8em;
|
||||
}
|
||||
&.wo-touch-active {
|
||||
background: $color-touch-active;
|
||||
}
|
||||
}
|
||||
&__actions {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
text-align: center;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
|
||||
// has to be same as label
|
||||
box-sizing: content-box;
|
||||
padding: 10px 15px;
|
||||
line-height: 24px;
|
||||
height: 24px;
|
||||
|
||||
& > li {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
@include respond-to(md) {
|
||||
justify-content: flex-end;
|
||||
& > li {
|
||||
flex-grow: 0;
|
||||
padding-left: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// Container for mail list entries
|
||||
.mail-list {
|
||||
$padding-horizontal: 15px;
|
||||
$padding-vertical: 10px;
|
||||
$padding-vertical: 15px;
|
||||
$footer-height: 30px;
|
||||
|
||||
// do not share any common styles between large and other screens
|
||||
@ -18,7 +18,7 @@
|
||||
& > header {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
padding: $padding-horizontal ($padding-vertical + 5px);
|
||||
padding: $padding-vertical $padding-horizontal;
|
||||
cursor: pointer;
|
||||
|
||||
.btn-navicon {
|
||||
@ -33,11 +33,15 @@
|
||||
font-size: $font-size-bigger;
|
||||
font-weight: normal;
|
||||
}
|
||||
.btn-icon {
|
||||
.btn-icon-light {
|
||||
position: absolute;
|
||||
top: $padding-vertical;
|
||||
right: $padding-horizontal;
|
||||
margin-top: -0.05em; // for perfect vertical alignment with headline
|
||||
padding-left: 1em;
|
||||
& > svg {
|
||||
width: 2em;
|
||||
height: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
&.wo-touch-active {
|
||||
@ -78,18 +82,8 @@
|
||||
width: 100%;
|
||||
font-size: $font-size-smaller;
|
||||
color: $color-text;
|
||||
line-height: $footer-height - 4px;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: $padding-horizontal;
|
||||
right: $padding-horizontal;
|
||||
height: 0;
|
||||
border-top: 1px solid $color-grey-medium;
|
||||
}
|
||||
line-height: $footer-height;
|
||||
border-top: 1px solid $color-border-light;
|
||||
|
||||
svg {
|
||||
display: inline-block;
|
||||
@ -107,7 +101,7 @@
|
||||
h2 {
|
||||
padding-right: 0;
|
||||
}
|
||||
.btn-icon {
|
||||
.btn-icon-light {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@ -248,8 +242,8 @@
|
||||
& > svg {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
width: 1.2em;
|
||||
height: 1.2em;
|
||||
fill: $color-main;
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,33 @@
|
||||
.read {
|
||||
$padding-horizontal: 15px;
|
||||
$padding-vertical: 10px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
@include respond-to(lg) {
|
||||
padding: 20px 20px 10px;
|
||||
// Toolbars
|
||||
|
||||
&__folder-toolbar {
|
||||
flex-shrink: 0;
|
||||
border-bottom: 1px solid $color-border-light;
|
||||
@include respond-to(md) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&__action-toolbar {
|
||||
flex-shrink: 0;
|
||||
order: 100; // stick to bottom on mobile
|
||||
border-top: 1px solid $color-border-light;
|
||||
@include respond-to(md) {
|
||||
order: initial;
|
||||
border-top: none;
|
||||
border-bottom: 1px solid $color-border-light;
|
||||
}
|
||||
@include respond-to(lg) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Header components
|
||||
@ -14,52 +35,67 @@
|
||||
&__header {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 1em;
|
||||
padding: $padding-vertical $padding-horizontal 0;
|
||||
|
||||
& > .attachments {
|
||||
margin-top: 1em;
|
||||
}
|
||||
}
|
||||
&__controls,
|
||||
&__controls-lg {
|
||||
// only visible in stripped version of read view
|
||||
.mail-addresses__stripped {
|
||||
display: none;
|
||||
}
|
||||
&__controls {
|
||||
display: none;
|
||||
float: right;
|
||||
margin-left: 1em;
|
||||
.btn-icon {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
.btn-icon-light {
|
||||
margin-left: 1em;
|
||||
}
|
||||
}
|
||||
&__controls {
|
||||
@include respond-to(lg) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&__controls-lg {
|
||||
display: none;
|
||||
@include respond-to(lg) {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
&__subject {
|
||||
font-size: $font-size-bigger;
|
||||
font-weight: bold;
|
||||
color: $color-text;
|
||||
margin: 0 0 0.2em;
|
||||
@include respond-to(not-md) {
|
||||
cursor: pointer;
|
||||
&.wo-touch-active {
|
||||
background: $color-touch-active;
|
||||
}
|
||||
.btn-icon-very-light {
|
||||
float: right;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
@include respond-to(md) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&__subject-md {
|
||||
display: none;
|
||||
font-size: $font-size-bigger;
|
||||
font-weight: normal;
|
||||
margin: 0 0 0.2em;
|
||||
& > svg {
|
||||
display: inline-block;
|
||||
display: none;
|
||||
fill: $color-main;
|
||||
vertical-align: baseline;
|
||||
height: 0.8em;
|
||||
width: 0.8em;
|
||||
|
||||
@include respond-to(md-only) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&.wo-touch-active {
|
||||
background: $color-touch-active;
|
||||
|
||||
@include respond-to(md) {
|
||||
display: block;
|
||||
}
|
||||
@include respond-to(lg) {
|
||||
cursor: pointer;
|
||||
& > svg {
|
||||
display: inline-block;
|
||||
}
|
||||
&.wo-touch-active {
|
||||
background: $color-touch-active;
|
||||
}
|
||||
}
|
||||
}
|
||||
&__time {
|
||||
@ -73,17 +109,21 @@
|
||||
|
||||
&__signature-status {
|
||||
flex-shrink: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5em;
|
||||
text-align: center;
|
||||
color: $color-error;
|
||||
padding: 0 $padding-horizontal;
|
||||
}
|
||||
&__display-images {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 0.5em;
|
||||
text-align: center;
|
||||
padding: 0 $padding-horizontal;
|
||||
}
|
||||
&__working {
|
||||
flex-grow: 1;
|
||||
padding: 0 $padding-horizontal;
|
||||
& > div {
|
||||
@include scut-vcenter-tt;
|
||||
width: 100%;
|
||||
@ -103,6 +143,7 @@
|
||||
// allow scrolling on iOS
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
padding: 0 $padding-horizontal $padding-vertical;
|
||||
|
||||
iframe {
|
||||
flex-grow: 1;
|
||||
@ -111,48 +152,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Popovers
|
||||
|
||||
// TODO: refactor to BEM
|
||||
.reply-selection {
|
||||
.popover-content {
|
||||
padding: 0;
|
||||
}
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
}
|
||||
li {
|
||||
border-bottom: 1px solid $color-border-light;
|
||||
&:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
button {
|
||||
display: block;
|
||||
background: none;
|
||||
width: 100%;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
padding: 0.5em 1em 0.5em 0.3em;
|
||||
color: $color-main;
|
||||
transition: background-color 0.3s;
|
||||
text-align: left;
|
||||
|
||||
& > svg {
|
||||
display: inline-block;
|
||||
width: 2em;
|
||||
height: 1em;
|
||||
vertical-align: middle;
|
||||
fill: $color-main;
|
||||
}
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: darken($color-white, 2%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Modifiers
|
||||
|
||||
&--no-attachments {
|
||||
@ -162,4 +161,17 @@
|
||||
border-bottom: 1px solid $color-border-light;
|
||||
}
|
||||
}
|
||||
@include respond-to(sm-only) {
|
||||
&--stripped {
|
||||
.read__addresses > * {
|
||||
display: none;
|
||||
&:first-child {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.mail-addresses__stripped {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@
|
||||
<h2>{{state.nav.currentFolder.type}}</h2>
|
||||
</div>
|
||||
|
||||
<button class="btn-icon" title="New mail" wo-touch="state.writer.write(); $event.stopPropagation()">
|
||||
<button class="btn-icon-light" title="New mail" wo-touch="state.writer.write(); $event.stopPropagation()">
|
||||
<svg><use xlink:href="#icon-write" /><title>New mail</title></svg>
|
||||
</button>
|
||||
</header>
|
||||
|
@ -1,56 +1,102 @@
|
||||
<div class="read" ng-controller="ReadCtrl"
|
||||
ng-class="{'read--no-attachments': !state.mailList.selected.attachments || state.mailList.selected.attachments.length === 0}">
|
||||
ng-class="{
|
||||
'read--no-attachments': !state.mailList.selected.attachments || state.mailList.selected.attachments.length === 0,
|
||||
'read--stripped': !notStripped
|
||||
}">
|
||||
|
||||
<div class="read__folder-toolbar">
|
||||
<div class="toolbar">
|
||||
<a class="toolbar__label" href="javascript:;" wo-touch="state.read.toggle(false)">
|
||||
<svg><use xlink:href="#icon-back" /><title>Back</title></svg> Folder name
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="read__action-toolbar">
|
||||
<div class="toolbar">
|
||||
<ul class="toolbar__actions">
|
||||
<li>
|
||||
<button class="btn-icon-light" ng-hide="true" title="Remove from favorites">
|
||||
<svg><use xlink:href="#icon-star_filled" /><title>Favorited</title></svg>
|
||||
</button>
|
||||
<button class="btn-icon-light" title="Add to favorites">
|
||||
<svg><use xlink:href="#icon-star" /><title>Favorite</title></svg>
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button class="btn-icon-light" title="Move mail">
|
||||
<svg><use xlink:href="#icon-folder" /><title>Move mail</title></svg>
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button wo-touch="state.mailList.remove(state.mailList.selected)" class="btn-icon-light" title="Delete mail">
|
||||
<svg><use xlink:href="#icon-trash" /><title>Delete mail</title></svg>
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button class="btn-icon-light" title="Reply to" wo-dropdown="#reply-selection" wo-dropdown-position="center">
|
||||
<svg><use xlink:href="#icon-reply_light" /><title>Reply to</title></svg>
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button wo-touch="state.writer.write()" class="btn-icon-light" title="New mail">
|
||||
<svg><use xlink:href="#icon-write" /><title>New mail</title></svg>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<header class="read__header">
|
||||
<div class="read__controls">
|
||||
<button wo-touch="state.mailList.remove(state.mailList.selected)" class="btn-icon" title="Delete mail">
|
||||
<svg><use xlink:href="#icon-delete" /><title>Delete mail</title></svg>
|
||||
</button>
|
||||
<button class="btn-icon" title="Reply to" wo-dropdown="#reply-selection" wo-dropdown-position="center">
|
||||
<svg><use xlink:href="#icon-reply" /><title>Reply to</title></svg>
|
||||
</button>
|
||||
<button wo-touch="state.writer.write()" class="btn-icon" title="New mail">
|
||||
<svg><use xlink:href="#icon-write" /><title>New mail</title></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="read__controls-lg">
|
||||
<button class="btn-icon-light" wo-touch="state.writer.write(state.mailList.selected)" title="Reply"><svg><use xlink:href="#icon-reply_light" /></svg></button>
|
||||
<button class="btn-icon-light" wo-touch="state.writer.write(state.mailList.selected, true)" title="Reply All"><svg><use xlink:href="#icon-reply_all_light" /></svg></button>
|
||||
<button class="btn-icon-light" wo-touch="state.writer.write(state.mailList.selected, null, true)" title="Forward"><svg><use xlink:href="#icon-forward_light" /></svg></button>
|
||||
</div>
|
||||
|
||||
<h2 class="read__subject" wo-touch="state.read.toggle(false)">
|
||||
<h2 class="read__subject" wo-touch="notStripped = !notStripped">
|
||||
<button ng-hide="notStripped" class="btn-icon-very-light">
|
||||
<svg><use xlink:href="#icon-dropdown" /><title>More</title></svg>
|
||||
</button>
|
||||
<button ng-show="notStripped" class="btn-icon-very-light">
|
||||
<svg><use xlink:href="#icon-dropup" /><title>Less</title></svg>
|
||||
</button>
|
||||
|
||||
{{state.mailList.selected.subject ? state.mailList.selected.subject : 'No subject'}}
|
||||
</h2>
|
||||
<h2 class="read__subject-md" wo-touch="state.read.toggle(false)">
|
||||
<svg><use xlink:href="#icon-back" /><title>Back</title></svg>
|
||||
{{state.mailList.selected.subject ? state.mailList.selected.subject : 'No subject'}}
|
||||
</h2>
|
||||
<time class="read__time">{{state.mailList.selected.sentDate | date:'EEEE, MMM d, yyyy h:mm a'}}</time>
|
||||
|
||||
<div class="mail-addresses">
|
||||
<label>From:</label>
|
||||
<span ng-repeat="u in state.mailList.selected.from">
|
||||
<span class="label" ng-class="{'label--invalid': u.secure === false, 'label--invalid-clickable': u.secure === false}" ng-mouseover="getKeyId(u.address)" wo-touch="invite(u)" wo-tooltip="#fingerprint-info">
|
||||
{{u.name || u.address}}
|
||||
<svg ng-show="u.secure === false"><use xlink:href="#icon-add_contact" /></svg>
|
||||
<div class="read__addresses">
|
||||
<div class="mail-addresses">
|
||||
<label>From:</label>
|
||||
<span ng-repeat="u in state.mailList.selected.from">
|
||||
<span class="label" ng-class="{'label--invalid': u.secure === false, 'label--invalid-clickable': u.secure === false}" ng-mouseover="getKeyId(u.address)" wo-touch="invite(u)" wo-tooltip="#fingerprint-info">
|
||||
{{u.name || u.address}}
|
||||
<svg ng-show="u.secure === false"><use xlink:href="#icon-add_contact" /></svg>
|
||||
</span>
|
||||
<span class="mail-addresses__stripped"></span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="mail-addresses">
|
||||
<label>To:</label>
|
||||
<span ng-repeat="u in state.mailList.selected.to">
|
||||
<span class="label" ng-class="{'label--invalid': u.secure === false, 'label--invalid-clickable': u.secure === false}" ng-mouseover="getKeyId(u.address)" wo-touch="invite(u)" wo-tooltip="#fingerprint-info">
|
||||
{{u.name || u.address}}
|
||||
<svg ng-show="u.secure === false"><use xlink:href="#icon-add_contact" /></svg>
|
||||
</div>
|
||||
<div class="mail-addresses">
|
||||
<label>To:</label>
|
||||
<span ng-repeat="u in state.mailList.selected.to">
|
||||
<span class="label" ng-class="{'label--invalid': u.secure === false, 'label--invalid-clickable': u.secure === false}" ng-mouseover="getKeyId(u.address)" wo-touch="invite(u)" wo-tooltip="#fingerprint-info">
|
||||
{{u.name || u.address}}
|
||||
<svg ng-show="u.secure === false"><use xlink:href="#icon-add_contact" /></svg>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="mail-addresses" ng-show="state.mailList.selected.cc && state.mailList.selected.cc.length > 0">
|
||||
<label>Cc:</label>
|
||||
<span ng-repeat="u in state.mailList.selected.cc">
|
||||
<span class="label" ng-class="{'label--invalid': u.secure === false, 'label--invalid-clickable': u.secure === false}" ng-mouseover="getKeyId(u.address)" wo-touch="invite(u)" wo-tooltip="#fingerprint-info">
|
||||
{{u.name || u.address}}
|
||||
<svg ng-show="u.secure === false"><use xlink:href="#icon-add_contact" /></svg>
|
||||
</div>
|
||||
<div class="mail-addresses" ng-show="state.mailList.selected.cc && state.mailList.selected.cc.length > 0">
|
||||
<label>Cc:</label>
|
||||
<span ng-repeat="u in state.mailList.selected.cc">
|
||||
<span class="label" ng-class="{'label--invalid': u.secure === false, 'label--invalid-clickable': u.secure === false}" ng-mouseover="getKeyId(u.address)" wo-touch="invite(u)" wo-tooltip="#fingerprint-info">
|
||||
{{u.name || u.address}}
|
||||
<svg ng-show="u.secure === false"><use xlink:href="#icon-add_contact" /></svg>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="attachments" ng-show="state.mailList.selected.attachments !== undefined && state.mailList.selected.attachments.length > 0">
|
||||
|
Loading…
Reference in New Issue
Block a user