1
0
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:
Mario Volke 2014-10-16 15:10:00 +02:00 committed by Tankred Hase
parent c9c05302d2
commit c3021a7244
9 changed files with 240 additions and 125 deletions

8
src/img/icons/dropup.svg Normal file
View 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

View File

@ -45,6 +45,7 @@
@import "blocks/basics/attachments"; @import "blocks/basics/attachments";
@import "blocks/basics/tooltip"; @import "blocks/basics/tooltip";
@import "blocks/basics/dropdown"; @import "blocks/basics/dropdown";
@import "blocks/basics/toolbar";
@import "blocks/layout/app"; @import "blocks/layout/app";
@import "blocks/layout/nav"; @import "blocks/layout/nav";
@import "blocks/layout/action-bar"; @import "blocks/layout/action-bar";

View File

@ -299,7 +299,6 @@
margin: 0; margin: 0;
font-size: $font-size-base; font-size: $font-size-base;
opacity: 0.5; opacity: 0.5;
transition: opacity 0.3s;
outline: 0; outline: 0;
&:focus, &:focus,

View File

@ -45,4 +45,8 @@
} }
} }
} }
&__stripped:after {
content: "";
}
} }

View 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;
}
}
}
}

View File

@ -1,7 +1,7 @@
// Container for mail list entries // Container for mail list entries
.mail-list { .mail-list {
$padding-horizontal: 15px; $padding-horizontal: 15px;
$padding-vertical: 10px; $padding-vertical: 15px;
$footer-height: 30px; $footer-height: 30px;
// do not share any common styles between large and other screens // do not share any common styles between large and other screens
@ -18,7 +18,7 @@
& > header { & > header {
position: relative; position: relative;
flex-shrink: 0; flex-shrink: 0;
padding: $padding-horizontal ($padding-vertical + 5px); padding: $padding-vertical $padding-horizontal;
cursor: pointer; cursor: pointer;
.btn-navicon { .btn-navicon {
@ -33,11 +33,15 @@
font-size: $font-size-bigger; font-size: $font-size-bigger;
font-weight: normal; font-weight: normal;
} }
.btn-icon { .btn-icon-light {
position: absolute; position: absolute;
top: $padding-vertical; top: $padding-vertical;
right: $padding-horizontal; right: $padding-horizontal;
margin-top: -0.05em; // for perfect vertical alignment with headline padding-left: 1em;
& > svg {
width: 2em;
height: 2em;
}
} }
&.wo-touch-active { &.wo-touch-active {
@ -78,18 +82,8 @@
width: 100%; width: 100%;
font-size: $font-size-smaller; font-size: $font-size-smaller;
color: $color-text; color: $color-text;
line-height: $footer-height - 4px; line-height: $footer-height;
border-top: 1px solid $color-border-light;
&:before {
content: '';
display: block;
position: absolute;
top: 0;
left: $padding-horizontal;
right: $padding-horizontal;
height: 0;
border-top: 1px solid $color-grey-medium;
}
svg { svg {
display: inline-block; display: inline-block;
@ -107,7 +101,7 @@
h2 { h2 {
padding-right: 0; padding-right: 0;
} }
.btn-icon { .btn-icon-light {
display: none; display: none;
} }
} }
@ -248,8 +242,8 @@
& > svg { & > svg {
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
width: 1em; width: 1.2em;
height: 1em; height: 1.2em;
fill: $color-main; fill: $color-main;
} }
} }

View File

@ -1,12 +1,33 @@
.read { .read {
$padding-horizontal: 15px;
$padding-vertical: 10px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 10px;
height: 100%; height: 100%;
width: 100%; width: 100%;
// 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) { @include respond-to(lg) {
padding: 20px 20px 10px; display: none;
}
} }
// Header components // Header components
@ -14,54 +35,69 @@
&__header { &__header {
flex-shrink: 0; flex-shrink: 0;
margin-bottom: 1em; margin-bottom: 1em;
padding: $padding-vertical $padding-horizontal 0;
& > .attachments { & > .attachments {
margin-top: 1em; margin-top: 1em;
} }
} }
&__controls, // only visible in stripped version of read view
&__controls-lg { .mail-addresses__stripped {
display: none;
}
&__controls {
display: none;
float: right; float: right;
margin-left: 1em; margin-left: 1em;
.btn-icon {
margin-left: 0.5em;
}
.btn-icon-light { .btn-icon-light {
margin-left: 1em; margin-left: 1em;
} }
}
&__controls {
@include respond-to(lg) {
display: none;
}
}
&__controls-lg {
display: none;
@include respond-to(lg) { @include respond-to(lg) {
display: block; display: block;
} }
} }
&__subject { &__subject {
font-size: $font-size-bigger; font-weight: bold;
color: $color-text;
margin: 0 0 0.2em; margin: 0 0 0.2em;
@include respond-to(not-md) { &.wo-touch-active {
cursor: pointer; 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 { & > svg {
display: inline-block; display: none;
fill: $color-main; fill: $color-main;
vertical-align: baseline; vertical-align: baseline;
height: 0.8em; height: 0.8em;
width: 0.8em; width: 0.8em;
@include respond-to(md-only) {
display: none;
} }
@include respond-to(md) {
display: block;
}
@include respond-to(lg) {
cursor: pointer;
& > svg {
display: inline-block;
} }
&.wo-touch-active { &.wo-touch-active {
background: $color-touch-active; background: $color-touch-active;
} }
} }
}
&__time { &__time {
display: block; display: block;
color: $color-text-light; color: $color-text-light;
@ -73,17 +109,21 @@
&__signature-status { &__signature-status {
flex-shrink: 0; flex-shrink: 0;
margin-top: 0;
margin-bottom: 0.5em; margin-bottom: 0.5em;
text-align: center; text-align: center;
color: $color-error; color: $color-error;
padding: 0 $padding-horizontal;
} }
&__display-images { &__display-images {
flex-shrink: 0; flex-shrink: 0;
margin-bottom: 0.5em; margin-bottom: 0.5em;
text-align: center; text-align: center;
padding: 0 $padding-horizontal;
} }
&__working { &__working {
flex-grow: 1; flex-grow: 1;
padding: 0 $padding-horizontal;
& > div { & > div {
@include scut-vcenter-tt; @include scut-vcenter-tt;
width: 100%; width: 100%;
@ -103,6 +143,7 @@
// allow scrolling on iOS // allow scrolling on iOS
overflow: auto; overflow: auto;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
padding: 0 $padding-horizontal $padding-vertical;
iframe { iframe {
flex-grow: 1; 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 // Modifiers
&--no-attachments { &--no-attachments {
@ -162,4 +161,17 @@
border-bottom: 1px solid $color-border-light; 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;
}
}
}
} }

View File

@ -8,7 +8,7 @@
<h2>{{state.nav.currentFolder.type}}</h2> <h2>{{state.nav.currentFolder.type}}</h2>
</div> </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> <svg><use xlink:href="#icon-write" /><title>New mail</title></svg>
</button> </button>
</header> </header>

View File

@ -1,30 +1,74 @@
<div class="read" ng-controller="ReadCtrl" <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
}">
<header class="read__header"> <div class="read__folder-toolbar">
<div class="read__controls"> <div class="toolbar">
<button wo-touch="state.mailList.remove(state.mailList.selected)" class="btn-icon" title="Delete mail"> <a class="toolbar__label" href="javascript:;" wo-touch="state.read.toggle(false)">
<svg><use xlink:href="#icon-delete" /><title>Delete mail</title></svg> <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>
<button class="btn-icon" title="Reply to" wo-dropdown="#reply-selection" wo-dropdown-position="center"> <button class="btn-icon-light" title="Add to favorites">
<svg><use xlink:href="#icon-reply" /><title>Reply to</title></svg> <svg><use xlink:href="#icon-star" /><title>Favorite</title></svg>
</button> </button>
<button wo-touch="state.writer.write()" class="btn-icon" title="New mail"> </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> <svg><use xlink:href="#icon-write" /><title>New mail</title></svg>
</button> </button>
</li>
</ul>
</div> </div>
<div class="read__controls-lg"> </div>
<header class="read__header">
<div class="read__controls">
<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)" 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, 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> <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> </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> <svg><use xlink:href="#icon-back" /><title>Back</title></svg>
{{state.mailList.selected.subject ? state.mailList.selected.subject : 'No subject'}} {{state.mailList.selected.subject ? state.mailList.selected.subject : 'No subject'}}
</h2> </h2>
<time class="read__time">{{state.mailList.selected.sentDate | date:'EEEE, MMM d, yyyy h:mm a'}}</time> <time class="read__time">{{state.mailList.selected.sentDate | date:'EEEE, MMM d, yyyy h:mm a'}}</time>
<div class="read__addresses">
<div class="mail-addresses"> <div class="mail-addresses">
<label>From:</label> <label>From:</label>
<span ng-repeat="u in state.mailList.selected.from"> <span ng-repeat="u in state.mailList.selected.from">
@ -32,6 +76,7 @@
{{u.name || u.address}} {{u.name || u.address}}
<svg ng-show="u.secure === false"><use xlink:href="#icon-add_contact" /></svg> <svg ng-show="u.secure === false"><use xlink:href="#icon-add_contact" /></svg>
</span> </span>
<span class="mail-addresses__stripped"></span>
</span> </span>
</div> </div>
<div class="mail-addresses"> <div class="mail-addresses">
@ -52,6 +97,7 @@
</span> </span>
</span> </span>
</div> </div>
</div>
<ul class="attachments" ng-show="state.mailList.selected.attachments !== undefined && state.mailList.selected.attachments.length > 0"> <ul class="attachments" ng-show="state.mailList.selected.attachments !== undefined && state.mailList.selected.attachments.length > 0">
<li ng-repeat="attachment in state.mailList.selected.attachments" <li ng-repeat="attachment in state.mailList.selected.attachments"