(web) Restore mail threads

Fixes #3478
Fixes #4616
Fixes #4735
This commit is contained in:
Francis Lachapelle
2019-06-27 17:43:11 -04:00
parent cc6fcc5fbd
commit b5949752b4
10 changed files with 142 additions and 20 deletions
@@ -266,6 +266,16 @@
'}'
].join(''));
// Register custom stylesheet for Mail module
$mdThemingProvider.registerStyles([
'.sg-message-thread {',
' background-color: \'{{primary-100}}\';',
'}',
'.sg-message-thread-first {',
' background-color: \'{{primary-200}}\';',
'}',
].join(''));
if (!window.DebugEnabled) {
// Disable debugging information
$logProvider.debugEnabled(false);
@@ -165,6 +165,9 @@
if (this.path) {
this.id = this.$id();
this.$acl = new Mailbox.$$Acl('Mail/' + this.id);
if (this.threaded) {
this.$collapsedThreads = Mailbox.$Preferences.settings.Mail.threadsCollapsed['/' + this.id] || [];
}
}
this.$displayName = this.name;
if (this.type) {
@@ -222,7 +225,16 @@
* @returns the number of messages in the mailbox
*/
Mailbox.prototype.getLength = function() {
return this.$messages.length;
var _this = this, collapsedThread = false;
var visibleMessages = _.filter(this.$messages, function(msg, i) {
if (msg.first) {
collapsedThread = msg.collapsed;
} else if (msg.level < 0) {
collapsedThread = false;
}
return msg.first || collapsedThread === false;
});
return visibleMessages.length;
};
/**
@@ -232,10 +244,18 @@
* @returns the message at the specified index
*/
Mailbox.prototype.getItemAtIndex = function(index) {
var message;
var _this = this, collapsedThread = false, message;
var visibleMessages = _.filter(this.$messages, function(msg, i) {
if (msg.first) {
collapsedThread = msg.collapsed;
} else if (msg.level < 0) {
collapsedThread = false; // leaving the thread
}
return msg.first || collapsedThread === false;
});
if (index >= 0 && index < this.$messages.length) {
message = this.$messages[index];
if (index >= 0 && index < visibleMessages.length) {
message = visibleMessages[index];
this.$lastVisibleIndex = Math.max(0, index - 3); // Magic number is NUM_EXTRA from virtual-repeater.js
if (this.$loadMessage(message.uid))
@@ -928,7 +948,7 @@
// First entry of 'uids' are keys when threaded view is enabled
if (_this.threaded) {
uids = _this.uids[0];
uids = _this.uids[0]; // uid, level, first
_this.uids.splice(0, 1);
}
@@ -937,6 +957,19 @@
var data, msgObject;
if (_this.threaded) {
data = _.zipObject(uids, msg);
if (data.first === 1) {
var count = 1;
while (_this.uids[i + count] &&
_this.uids[i + count][1] >= 0 &&
_this.uids[i + count][2] !== 1) {
count++;
}
data.count = count;
data.collapsed = false;
if (_this.$collapsedThreads.indexOf(data.uid.toString()) >= 0) {
data.collapsed = true;
}
}
} else {
data = {uid: msg.toString()};
}
@@ -26,6 +26,15 @@
this.init(futureMessageData);
}
this.uid = parseInt(futureMessageData.uid);
this.level = parseInt(futureMessageData.level);
this.first = parseInt(futureMessageData.first) === 1;
if (this.first) {
this.threadCount = parseInt(futureMessageData.count);
this.collapsed = (futureMessageData.collapsed === true);
}
else if (!isNaN(this.level) && this.level >= 0) {
this.threadMember = true;
}
}
else {
// The promise will be unwrapped first
@@ -539,7 +548,7 @@
};
/**
* @function $markAsFlaggedOrUnflagged
* @function toggleFlag
* @memberof Message.prototype
* @desc Add or remove a the \\Flagged flag on the current message.
* @returns a promise of the HTTP operation
@@ -558,6 +567,24 @@
});
};
/**
* @function toggleThread
* @memberof Message.prototype
* @desc Collapse or expand mail thread
* @returns a promise of the HTTP operation
*/
Message.prototype.toggleThread = function() {
var _this = this,
action = 'markMessageCollapse';
if (this.collapsed)
action = 'markMessageUncollapse';
this.collapsed = !this.collapsed;
return Message.$$resource.post(this.$absolutePath(), action);
};
/**
* @function $isLoading
* @memberof Message.prototype
@@ -26,6 +26,9 @@
' <div class="sg-md-body">',
' <div class="sg-tile-subject"><!-- subject --></div>',
' <div class="sg-tile-size"><!-- size --></div>',
' <md-button class="sg-tile-thread md-secondary ng-hide" md-colors="::{ color: \'accent-600\'}" ng-click="$ctrl.toggleThread()">',
' <md-icon class="md-rotate-180-ccw" md-colors="::{ color: \'accent-600\'}">expand_more</md-icon><span><span>', // expanded by default (icon is rotated)
' </md-button>',
' </div>',
'</div>',
'<div class="sg-tile-icons">',
@@ -59,7 +62,7 @@
var $ctrl = this;
this.$postLink = function () {
var contentDivElement, iconsDivElement;
var contentDivElement, threadButton, iconsDivElement;
var parentControllerOnUpdate, setVisibility;
this.parentController = $scope.parentController;
@@ -74,6 +77,12 @@
iconsDivElement = angular.element(div);
});
threadButton = contentDivElement.find('button')[0];
this.threadButton = threadButton;
threadButton = angular.element(threadButton);
this.threadIconElement = threadButton.find('md-icon')[0];
this.threadCountElement = threadButton.find('span')[0];
this.priorityIconElement = contentDivElement.find('md-icon')[0];
if (Mailbox.$virtualMode) {
@@ -147,9 +156,19 @@
else
$ctrl.priorityIconElement.classList.add('ng-hide');
// Mail thread
if ($ctrl.message.first) {
$ctrl.threadButton.classList.remove('ng-hide');
$ctrl.threadCountElement.innerHTML = $ctrl.message.threadCount;
if ($ctrl.message.collapsed)
$ctrl.threadIconElement.classList.remove('md-rotate-180-ccw');
}
else {
$ctrl.threadButton.classList.add('ng-hide');
}
// Subject
$ctrl.subjectElement.innerHTML = $ctrl.message.subject.encodeEntities();
// Message size
$ctrl.sizeElement.innerHTML = $ctrl.message.size;
@@ -173,6 +192,14 @@
this.MailboxService = Mailbox;
};
this.toggleThread = function() {
if (this.message.collapsed)
this.threadIconElement.classList.add('md-rotate-180-ccw');
else
this.threadIconElement.classList.remove('md-rotate-180-ccw');
this.message.toggleThread();
};
}
@@ -11,7 +11,7 @@
var _this = this, defaultsElement, settingsElement, data;
this.defaults = {};
this.settings = {};
this.settings = {Mail: {}};
defaultsElement = Preferences.$document[0].getElementById('UserDefaults');
if (defaultsElement) {