Merge pull request #216 from whiteout-io/dev/WO-751

[WO-751] Add flagging messages
This commit is contained in:
Tankred Hase 2014-12-03 09:46:18 +01:00
commit 9d8fc023ca
8 changed files with 148 additions and 19 deletions

View File

@ -114,7 +114,7 @@ var ActionBarCtrl = function($scope, email, dialog, statusDisplay) {
* @param {boolean} unread If the message should be marked as read or unread
*/
$scope.markMessage = function(message, unread, keepOpen) {
if (!message) {
if (!message || message.unread === unread) {
return;
}
@ -159,9 +159,56 @@ var ActionBarCtrl = function($scope, email, dialog, statusDisplay) {
});
};
/**
* Flag a single message
* @param {Object} message The message to be flagged
* @param {boolean} flagged If the message should be flagged or unflagged
*/
$scope.flagMessage = function(message, flagged) {
if (!message || message.flagged === flagged) {
return;
}
statusDisplay.update(flagged ? 'Adding message to favorites...' : 'Removing message from favorites');
var originalState = message.flagged;
message.flagged = flagged;
email.setFlags({
folder: currentFolder(),
message: message
}, function(err) {
if (err && err.code === 42) {
// offline, restore
message.unread = originalState;
statusDisplay.update('Unable to ' + (flagged ? 'add message to' : 'remove message from') + ' favorites in offline mode!');
return;
}
if (err) {
statusDisplay.update('Error on sync!');
dialog.error(err);
return;
}
statusDisplay.update('Online');
$scope.$apply();
});
};
/**
* Mark all of the checked messages as either flagged or unflagged.
* @param {boolean} flagged If the message should be marked as flagged or unflagged
*/
$scope.flagCheckedMessages = function(flagged) {
getCheckMessages().forEach(function(message) {
$scope.flagMessage(message, flagged);
});
};
// share local scope functions with root state
$scope.state.actionBar = {
markMessage: $scope.markMessage
markMessage: $scope.markMessage,
flagMessage: $scope.flagMessage
};
function currentFolder() {

View File

@ -98,6 +98,10 @@ var MailListCtrl = function($scope, $timeout, $routeParams, $filter, statusDispl
}
};
$scope.flag = function(message, flagged) {
$scope.state.actionBar.flagMessage(message, flagged);
};
/**
* Date formatting
*/

View File

@ -368,12 +368,16 @@
.checkbox {
vertical-align: middle;
// add invisible padding to make increase clickable area around checkbox
// add invisible padding to increase clickable area around checkbox
margin: -0.5em 0 -0.5em -1em;
padding: 0.5em 0 0.5em 1em;
}
}
&__flags-favorite {
// add invisible padding to increase clickable area around star
margin: -0.5em 0 -0.5em;
padding: 0.5em 0 0.5em;
& > svg {
fill: $color-text-light;
&:first-child {

View File

@ -37,5 +37,7 @@
<ul id="dropdown-more" class="dropdown">
<li><button wo-touch="state.read.open ? markMessage(state.mailList.selected, false) : markCheckedMessages(false)">Mark as read</button></li>
<li><button wo-touch="state.read.open ? markMessage(state.mailList.selected, true) : markCheckedMessages(true)">Mark as unread</button></li>
<li><button wo-touch="state.read.open ? flagMessage(state.mailList.selected, true) : flagCheckedMessages(true)">Flag message</button></li>
<li><button wo-touch="state.read.open ? flagMessage(state.mailList.selected, false) : flagCheckedMessages(false)">Unflag message</button></li>
</ul><!--/dropdown-->
</div>

View File

@ -37,9 +37,9 @@
<span><svg role="presentation"><use xlink:href="#icon-check" /></svg></span>
</label>
</li>
<li class="mail-list-entry__flags-favorite">
<svg ng-show="false"><use xlink:href="#icon-star_filled" /><title>Favorited</title></svg>
<svg><use xlink:href="#icon-star" /><title>Favorite</title></svg>
<li class="mail-list-entry__flags-favorite" wo-touch="flag(email, !email.flagged); $event.stopPropagation()">
<svg ng-show="email.flagged"><use xlink:href="#icon-star_filled" /><title>Favorited</title></svg>
<svg ng-show="!email.flagged"><use xlink:href="#icon-star" /><title>Not Favorited</title></svg>
</li>
<li class="mail-list-entry__flags-encrypted">
<svg ng-show="email.encrypted"><use xlink:href="#icon-encrypted" /><title>Encrypted</title></svg>

View File

@ -16,11 +16,9 @@
<header class="read__header">
<div class="read__controls">
<span class="u-hidden-lg" ng-controller="ActionBarCtrl">
<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 wo-touch="flagMessage(state.mailList.selected, !state.mailList.selected.flagged)" class="btn-icon-light" title="{{state.mailList.selected.flagged ? 'Remove from Favorites' : 'Add to Favorites'}}">
<svg ng-show="state.mailList.selected.flagged"><use xlink:href="#icon-star_filled" /><title>Favorited</title></svg>
<svg ng-show="!state.mailList.selected.flagged"><use xlink:href="#icon-star" /><title>Not Favorited</title></svg>
</button>
<button class="btn-icon-light" title="Move mail" wo-dropdown="#read-dropdown-folder" wo-dropdown-position="center">
<svg><use xlink:href="#icon-folder" /><title>Move mail</title></svg>
@ -130,11 +128,9 @@
<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 wo-touch="flagMessage(state.mailList.selected, !state.mailList.selected.flagged)" class="btn-icon-light" title="{{state.mailList.selected.flagged ? 'Remove from Favorites' : 'Add to Favorites'}}">
<svg ng-show="state.mailList.selected.flagged"><use xlink:href="#icon-star_filled" /><title>Favorited</title></svg>
<svg ng-show="!state.mailList.selected.flagged"><use xlink:href="#icon-star" /><title>Not Favorited</title></svg>
</button>
</li>
<li>

View File

@ -138,11 +138,21 @@ describe('Action Bar Controller unit test', function() {
});
describe('markMessage', function() {
it('should not move without a selected mail', function() {
it('should not mark without a selected mail', function() {
scope.markMessage();
});
it('should move the selected mail', function() {
it('should not mark when old and new changes are equivalent', function() {
scope.markMessage({
unread: false
}, false);
scope.markMessage({
unread: true
}, true);
});
it('should mark the selected mail', function() {
emailMock.setFlags.yields();
scope.markMessage({}, true);
@ -162,11 +172,52 @@ describe('Action Bar Controller unit test', function() {
markMessageStub.restore();
});
it('should delete the selected mail', function() {
it('should mark the selected mail', function() {
scope.markCheckedMessages();
expect(markMessageStub.calledOnce).to.be.true;
});
});
describe('flagMessage', function() {
it('should not flag without a selected mail', function() {
scope.flagMessage();
});
it('should not flag when old and new changes are equivalent', function() {
scope.flagMessage({
flagged: false
}, false);
scope.flagMessage({
flagged: true
}, true);
});
it('should flag the selected mail', function() {
emailMock.setFlags.yields();
scope.flagMessage({}, true);
expect(emailMock.setFlags.calledOnce).to.be.true;
});
});
describe('flagCheckedMessages', function() {
var flagMessageStub;
beforeEach(function() {
flagMessageStub = sinon.stub(scope, 'flagMessage');
});
afterEach(function() {
flagMessageStub.restore();
});
it('should delete the selected mail', function() {
scope.flagCheckedMessages();
expect(flagMessageStub.calledOnce).to.be.true;
});
});
});

View File

@ -252,6 +252,31 @@ describe('Mail List controller unit test', function() {
});
});
describe('flag', function() {
it('should flag or unflag a message', function() {
var mail = {
from: [{
address: 'asd'
}],
flagged: true,
};
scope.state = {
actionBar: {
flagMessage: function(mail, flagged) {
mail.flagged = flagged;
}
}
};
scope.flag(mail, false);
expect(mail.flagged).to.be.false;
scope.flag(mail, true);
expect(mail.flagged).to.be.true;
});
});
describe('select', function() {
it('should decrypt, focus mark an unread mail as read', function() {
scope.pendingNotifications = ['asd'];