mirror of
https://github.com/moparisthebest/mail
synced 2024-11-26 19:02:20 -05:00
refactor mail list
This commit is contained in:
parent
a82c2ca20a
commit
342105cb4c
@ -14,6 +14,10 @@ define(function(require) {
|
||||
num = 100,
|
||||
firstSelect = true;
|
||||
|
||||
//
|
||||
// Init
|
||||
//
|
||||
|
||||
emailDao = appController._emailDao;
|
||||
if (emailDao) {
|
||||
emailDao.onIncomingMessage = function(email) {
|
||||
@ -50,7 +54,7 @@ define(function(require) {
|
||||
// scope functions
|
||||
//
|
||||
|
||||
$scope.$parent.select = $scope.select = function(email) {
|
||||
$scope.select = function(email) {
|
||||
if (!email) {
|
||||
return;
|
||||
}
|
||||
@ -64,15 +68,14 @@ define(function(require) {
|
||||
}
|
||||
});
|
||||
}
|
||||
$scope.selected = email;
|
||||
// set selected in parent scope ro it can be displayed in the read view
|
||||
$scope.$parent.selected = $scope.selected;
|
||||
|
||||
$scope.state.mailList.selected = email;
|
||||
|
||||
// mark selected message as 'read'
|
||||
markAsRead(email);
|
||||
};
|
||||
|
||||
$scope.$parent.synchronize = $scope.synchronize = function(callback) {
|
||||
$scope.synchronize = function(callback) {
|
||||
updateStatus('Syncing ...');
|
||||
// sync from imap to local db
|
||||
syncImapFolder({
|
||||
@ -94,7 +97,60 @@ define(function(require) {
|
||||
});
|
||||
};
|
||||
|
||||
$scope.$watch('currentFolder', function() {
|
||||
$scope.remove = function(email) {
|
||||
if (!email) {
|
||||
return;
|
||||
}
|
||||
|
||||
var index;
|
||||
removeLocalAndShowNext();
|
||||
removeRemote();
|
||||
|
||||
function removeLocalAndShowNext() {
|
||||
index = $scope.emails.indexOf(email);
|
||||
// show the next mail
|
||||
if ($scope.emails.length > 1) {
|
||||
// if we're about to delete the last entry of the array, show the previous (i.e. the one below in the list),
|
||||
// otherwise show the next one (i.e. the one above in the list)
|
||||
$scope.select(_.last($scope.emails) === email ? $scope.emails[index - 1] : $scope.emails[index + 1]);
|
||||
} else {
|
||||
// if we have only one email in the array, show nothing
|
||||
$scope.select();
|
||||
$scope.state.mailList.selected = undefined;
|
||||
}
|
||||
$scope.emails.splice(index, 1);
|
||||
}
|
||||
|
||||
function removeRemote() {
|
||||
var trashFolder = _.findWhere($scope.folders, {
|
||||
type: 'Trash'
|
||||
});
|
||||
if (getFolder() === trashFolder) {
|
||||
emailDao.imapDeleteMessage({
|
||||
folder: getFolder().path,
|
||||
uid: email.uid
|
||||
}, moved);
|
||||
return;
|
||||
}
|
||||
|
||||
emailDao.imapMoveMessage({
|
||||
folder: getFolder().path,
|
||||
uid: email.uid,
|
||||
destination: trashFolder.path
|
||||
}, moved);
|
||||
}
|
||||
|
||||
function moved(err) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
$scope.emails.splice(index, 0, email);
|
||||
$scope.$apply();
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.$watch('state.nav.currentFolder', function() {
|
||||
if (!getFolder()) {
|
||||
return;
|
||||
}
|
||||
@ -108,10 +164,16 @@ define(function(require) {
|
||||
// development... display dummy mail objects
|
||||
firstSelect = true;
|
||||
updateStatus('Last update: ', new Date());
|
||||
$scope.$parent.emails = $scope.emails = createDummyMails();
|
||||
$scope.emails = createDummyMails();
|
||||
$scope.select($scope.emails[0]);
|
||||
});
|
||||
|
||||
// share local scope functions with root state
|
||||
$scope.state.mailList = {
|
||||
remove: $scope.remove,
|
||||
synchronize: $scope.synchronize
|
||||
};
|
||||
|
||||
//
|
||||
// helper functions
|
||||
//
|
||||
@ -185,8 +247,6 @@ define(function(require) {
|
||||
function updateStatus(lbl, time) {
|
||||
$scope.lastUpdateLbl = lbl;
|
||||
$scope.lastUpdate = (time) ? time : '';
|
||||
$scope.$parent.lastUpdateLbl = $scope.lastUpdateLbl;
|
||||
$scope.$parent.lastUpdate = $scope.lastUpdate;
|
||||
}
|
||||
|
||||
function displayEmails(emails) {
|
||||
@ -202,13 +262,13 @@ define(function(require) {
|
||||
return -e.uid;
|
||||
});
|
||||
|
||||
$scope.$parent.emails = $scope.emails = emails;
|
||||
$scope.emails = emails;
|
||||
$scope.select($scope.emails[0]);
|
||||
$scope.$apply();
|
||||
}
|
||||
|
||||
function getFolder() {
|
||||
return $scope.$parent.currentFolder;
|
||||
return $scope.state.nav.currentFolder;
|
||||
}
|
||||
|
||||
function markAsRead(email) {
|
||||
|
@ -39,7 +39,7 @@ define(function(require) {
|
||||
};
|
||||
|
||||
$scope.openFolder = function(folder) {
|
||||
$scope.currentFolder = folder;
|
||||
$scope.state.nav.currentFolder = folder;
|
||||
$scope.state.nav.toggle(false);
|
||||
};
|
||||
|
||||
@ -50,59 +50,6 @@ define(function(require) {
|
||||
$scope.accountOpen = false;
|
||||
};
|
||||
|
||||
$scope.remove = function(email) {
|
||||
if (!email) {
|
||||
return;
|
||||
}
|
||||
|
||||
var index;
|
||||
removeLocalAndShowNext();
|
||||
removeRemote();
|
||||
|
||||
function removeLocalAndShowNext() {
|
||||
index = $scope.emails.indexOf(email);
|
||||
// show the next mail
|
||||
if ($scope.emails.length > 1) {
|
||||
// if we're about to delete the last entry of the array, show the previous (i.e. the one below in the list),
|
||||
// otherwise show the next one (i.e. the one above in the list)
|
||||
$scope.select(_.last($scope.emails) === email ? $scope.emails[index - 1] : $scope.emails[index + 1]);
|
||||
} else {
|
||||
// if we have only one email in the array, show nothing
|
||||
$scope.select();
|
||||
$scope.selected = undefined;
|
||||
}
|
||||
$scope.emails.splice(index, 1);
|
||||
}
|
||||
|
||||
function removeRemote() {
|
||||
var trashFolder = _.findWhere($scope.folders, {
|
||||
type: 'Trash'
|
||||
});
|
||||
if ($scope.currentFolder === trashFolder) {
|
||||
emailDao.imapDeleteMessage({
|
||||
folder: $scope.currentFolder.path,
|
||||
uid: email.uid
|
||||
}, moved);
|
||||
return;
|
||||
}
|
||||
|
||||
emailDao.imapMoveMessage({
|
||||
folder: $scope.currentFolder.path,
|
||||
uid: email.uid,
|
||||
destination: trashFolder.path
|
||||
}, moved);
|
||||
}
|
||||
|
||||
function moved(err) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
$scope.emails.splice(index, 0, email);
|
||||
$scope.$apply();
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.emptyOutbox = function() {
|
||||
var dbType = 'email_OUTBOX',
|
||||
outbox = _.findWhere($scope.folders, {
|
||||
@ -267,15 +214,20 @@ define(function(require) {
|
||||
elm.bind('keydown', function(e) {
|
||||
var cs = scope.$$childTail;
|
||||
|
||||
if (e.keyCode === 78 && !scope.state.writer.open) {
|
||||
// global state is not yet set, ignore keybaord shortcuts
|
||||
if (!scope.state) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.keyCode === 78 && scope.state.writer && !scope.state.writer.open) {
|
||||
// n -> new mail
|
||||
e.preventDefault();
|
||||
scope.state.writer.write();
|
||||
|
||||
} else if (e.keyCode === 82 && !scope.state.writer.open && cs.selected) {
|
||||
} else if (e.keyCode === 82 && scope.state.writer && !scope.state.writer.open && scope.state.mailList.selected) {
|
||||
// r -> reply
|
||||
e.preventDefault();
|
||||
scope.state.writer.write(cs.selected);
|
||||
scope.state.writer.write(scope.state.mailList.selected);
|
||||
|
||||
} else if (e.keyCode === 27 && scope.state.writer.open) {
|
||||
// escape -> close writer
|
||||
@ -287,10 +239,10 @@ define(function(require) {
|
||||
e.preventDefault();
|
||||
cs.closeAccount();
|
||||
|
||||
} else if (e.keyCode === 83 && !scope.state.writer.open && cs.synchronize) {
|
||||
} else if (e.keyCode === 83 && scope.state.writer && !scope.state.writer.open && scope.state.mailList.synchronize) {
|
||||
// s -> sync folder
|
||||
e.preventDefault();
|
||||
cs.synchronize();
|
||||
scope.state.mailList.synchronize();
|
||||
}
|
||||
|
||||
scope.$apply();
|
||||
|
@ -166,7 +166,7 @@ define(function(require) {
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.closeWriter();
|
||||
$scope.state.writer.close();
|
||||
$scope.$apply();
|
||||
$scope.emptyOutbox();
|
||||
});
|
||||
|
@ -8,7 +8,7 @@
|
||||
<section class="content main-content" ng-class="{'shift-right': state.read.open}">
|
||||
|
||||
<!-- left column: containing list view and navigation header -->
|
||||
<div class="column column-left" ng-include="'tpl/mail-list.html'" ng-controller="MailListCtrl"></div>
|
||||
<div class="column column-left" ng-include="'tpl/mail-list.html'"></div>
|
||||
|
||||
<!-- right column: containing list read view -->
|
||||
<div class="column" ng-include="'tpl/read.html'"></div>
|
||||
|
@ -1,12 +1,12 @@
|
||||
<div class="view-mail-list">
|
||||
<div class="view-mail-list" ng-controller="MailListCtrl">
|
||||
<!-- nav controll and section headline -->
|
||||
<header data-icon="" ng-click="state.nav.toggle(true); $event.stopPropagation()">
|
||||
<h2>{{currentFolder.type}}</h2>
|
||||
<h2>{{state.nav.currentFolder.type}}</h2>
|
||||
</header>
|
||||
|
||||
<div class="list-wrapper" ng-iscroll>
|
||||
<ul class="mail-list">
|
||||
<li ng-class="{'mail-list-active': email === selected, 'mail-list-attachment': email.attachments !== undefined && email.attachments.length > 0, 'mail-list-unread': email.unread, 'mail-list-replied': email.answered}" ng-click="select(email)" ng-repeat="email in emails">
|
||||
<li ng-class="{'mail-list-active': email === state.mailList.selected, 'mail-list-attachment': email.attachments !== undefined && email.attachments.length > 0, 'mail-list-unread': email.unread, 'mail-list-replied': email.answered}" ng-click="select(email)" ng-repeat="email in emails">
|
||||
<h3>{{email.from[0].name || email.from[0].address}}</h3>
|
||||
<div class="head">
|
||||
<p class="subject">{{email.subject || 'No subject'}}</p>
|
||||
|
@ -1,29 +1,29 @@
|
||||
<div class="controls">
|
||||
<button ng-click="remove(selected)" class="btn-icon" title="Delete mail"></button>
|
||||
<button ng-click="state.writer.write(selected)" class="btn-icon" title="Reply to"></button>
|
||||
<button ng-click="state.mailList.remove(state.mailList.selected)" class="btn-icon" title="Delete mail"></button>
|
||||
<button ng-click="state.writer.write(state.mailList.selected)" class="btn-icon" title="Reply to"></button>
|
||||
<button ng-click="state.writer.write()" class="btn-icon" title="New mail"></button>
|
||||
</div><!--/.controls-->
|
||||
|
||||
<div class="view-read" ng-controller="ReadCtrl">
|
||||
<div class="headers">
|
||||
<p class="subject" ng-click="state.read.toggle(false)">{{selected.subject || 'No subject'}}</p>
|
||||
<p class="date">{{selected.sentDate | date:'EEEE, MMM d, yyyy h:mm a'}}</p>
|
||||
<p class="address">From: <span class="label" data-icon-append="">{{selected.from[0].name || selected.from[0].address}}</span></p>
|
||||
<p class="address">To: <span class="label" data-icon-append="" ng-repeat="t in selected.to">{{t.address}} </span></p>
|
||||
<div ng-switch="selected.cc !== undefined">
|
||||
<p class="subject" ng-click="state.read.toggle(false)">{{state.mailList.selected.subject || 'No subject'}}</p>
|
||||
<p class="date">{{state.mailList.selected.sentDate | date:'EEEE, MMM d, yyyy h:mm a'}}</p>
|
||||
<p class="address">From: <span class="label" data-icon-append="">{{state.mailList.selected.from[0].name || state.mailList.selected.from[0].address}}</span></p>
|
||||
<p class="address">To: <span class="label" data-icon-append="" ng-repeat="t in state.mailList.selected.to">{{t.address}} </span></p>
|
||||
<div ng-switch="state.mailList.selected.cc !== undefined">
|
||||
<p class="address" ng-switch-when="true">
|
||||
CC: <span class="label" ng-repeat="t in selected.cc">{{t.address}} </span>
|
||||
CC: <span class="label" ng-repeat="t in state.mailList.selected.cc">{{t.address}} </span>
|
||||
</p>
|
||||
</div>
|
||||
</div><!--/.headers-->
|
||||
|
||||
<div class="seperator-line"></div>
|
||||
|
||||
<div class="body" ng-switch="selected.html === true">
|
||||
<div class="body" ng-switch="state.mailList.selected.html === true">
|
||||
<!-- sandbox untrusted markup from html emails in an iframe. The "allow-same-origin" attribute is required to dynamically adjust the height of the iframe. Script execution is not allowed. -->
|
||||
<iframe ng-switch-when="true" sandbox="allow-same-origin" srcdoc="{{selected.body}}" seamless frame-load></iframe>
|
||||
<iframe ng-switch-when="true" sandbox="allow-same-origin" srcdoc="{{state.mailList.selected.body}}" seamless frame-load></iframe>
|
||||
|
||||
<!-- Render parts of a text only email in paragraphs for easier styling -->
|
||||
<p ng-repeat="part in selected.bodyDisplayParts track by $index">{{part}}</p>
|
||||
<p ng-repeat="part in state.mailList.selected.bodyDisplayParts track by $index">{{part}}</p>
|
||||
</div><!--/.body-->
|
||||
</div><!--/.view-read-->
|
@ -9,7 +9,7 @@
|
||||
<div class="headers">
|
||||
<p>
|
||||
<span>To:</span>
|
||||
<input type="email" ng-model="to" ng-change="verifyTo()" ng-class="{'label': toSecure === true, 'label label-primary': toSecure === false}" tabindex="1" focus-me="writerOpen && !writerReply" auto-size="to" spellcheck="false">
|
||||
<input type="email" ng-model="to" ng-change="verifyTo()" ng-class="{'label': toSecure === true, 'label label-primary': toSecure === false}" tabindex="1" focus-me="state.writer.open && writerTitle !== 'Reply'" auto-size="to" spellcheck="false">
|
||||
</p>
|
||||
<p>
|
||||
<span>Cc:</span>
|
||||
@ -27,7 +27,7 @@
|
||||
</div><!--/.subject-box-->
|
||||
|
||||
<div class="body">
|
||||
<p ng-model="body" contentEditable="true" ng-change="updatePreview()" tabindex="4" focus-me="writerOpen && writerReply"></p>
|
||||
<p ng-model="body" contentEditable="true" ng-change="updatePreview()" tabindex="4" focus-me="state.writer.open && writerTitle === 'Reply'"></p>
|
||||
|
||||
<div class="encrypt-preview">
|
||||
<p>-----BEGIN ENCRYPTED PREVIEW-----<br>{{ciphertextPreview}}<br>-----END ENCRYPTED PREVIEW-----</p>
|
||||
|
Loading…
Reference in New Issue
Block a user