VulpesOS/gaia/apps/email/js/cards/lst/edit_controller.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

190 lines
6 KiB
JavaScript
Executable file

'use strict';
define(function(require, exports) {
var cards = require('cards'),
ConfirmDialog = require('confirm_dialog'),
deleteConfirmMsgNode = require('tmpl!../msg/delete_confirm.html'),
mozL10n = require('l10n!'),
toaster = require('toaster');
return {
createdCallback: function() {
this.editMode = false;
this.selectedMessages = null;
this.editModeEnabled = false;
},
setEditMode: function(editMode) {
// Do not bother if edit mode is not enabled yet.
if (!this.editModeEnabled) {
return;
}
this._setEditMode(editMode);
},
// This function is called from setEditMode() after ensuring that
// the backend is in a state where we can safely use edit mode.
_setEditMode: function(editMode) {
var i;
this.editMode = editMode;
if (editMode) {
this.classList.add('show-edit');
this.selectedMessages = [];
this.updateDomEditControls();
}
else {
this.classList.remove('show-edit');
this.selectedMessages = null;
}
// Reset checked mode for all message items.
var msgNodes = this.msgVScroll.querySelectorAll('.msg-header-item');
for (i = 0; i < msgNodes.length; i++) {
this.updateDomMessageChecked(msgNodes[i], false);
}
if (this.editModeChanged) {
this.editModeChanged(editMode);
}
},
// Event handler wired up in HTML template
setEditModeStart: function() {
this.setEditMode(true);
},
// Event handler wired up in HTML template
editHeaderClose: function() {
this.setEditMode(false);
},
/**
* Toggles the selection state of the node and therefore the stored
* `selectedMessages` state based on the previous state of the selection.
* The change in the total number of selections is then reflected in DOM
* updates.
* @param {Element} msgNode
*/
toggleSelection: function(msgNode) {
var header = msgNode.message;
var idx = this.selectedMessages.indexOf(header);
if (idx !== -1) {
this.selectedMessages.splice(idx, 1);
} else {
this.selectedMessages.push(header);
}
this.updateDomMessageChecked(msgNode, idx === -1);
this.updateDomEditControls();
},
/**
* Set or unset the select state on a node based on the edit mode.
*/
updateDomSelectState: function(msgNode, message) {
if (this.editMode) {
this.updateDomMessageChecked(msgNode,
this.selectedMessages.indexOf(message) !== -1);
} else {
msgNode.removeAttribute('aria-selected');
}
},
/**
* Set the checked state for the message item in the list. It sets both
* checkbox checked and aria-selected states.
*/
updateDomMessageChecked: function(msgNode, checked) {
var checkbox = msgNode.querySelector('input[type=checkbox]');
checkbox.checked = checked;
msgNode.setAttribute('aria-selected', checked);
},
/**
* Update the edit mode UI bits sensitive to a change in the set of selected
* messages. This means the label that says how many messages are selected,
* whether the buttons are enabled, which of the toggle-pairs are visible.
*/
updateDomEditControls: function() {
this.editHeader.updateDomHeaderCount(this.selectedMessages.length);
this.editToolbar.updateDomEditButtons(this.selectedMessages.length > 0);
// Enabling/disabling rules (not UX-signed-off): Our bias is that people
// want to star messages and mark messages unread (since it they naturally
// end up unread), so unless messages are all in this state, we assume
// that is the desired action.
var numStarred = 0, numRead = 0;
for (var i = 0; i < this.selectedMessages.length; i++) {
var msg = this.selectedMessages[i];
if (msg.isStarred) {
numStarred++;
}
if (msg.isRead) {
numRead++;
}
}
// Unstar if everything is starred, otherwise star
this.setAsStarred = !(numStarred && numStarred ===
this.selectedMessages.length);
this.editToolbar.updateDomStartButton(this.setAsStarred);
// Mark read if everything is unread, otherwise unread
this.setAsRead = (!!this.selectedMessages.length && numRead === 0);
this.editToolbar.updateDomReadButton(numRead > 0);
},
onDeleteMessages: function() {
if (this.selectedMessages.length === 0) {
return this.setEditMode(false);
}
var dialog = deleteConfirmMsgNode.cloneNode(true);
var content = dialog.getElementsByTagName('p')[0];
mozL10n.setAttributes(content, 'message-multiedit-delete-confirm',
{ n: this.selectedMessages.length });
ConfirmDialog.show(dialog,
{ // Confirm
id: 'msg-delete-ok',
handler: function() {
var op = this.model.api.deleteMessages(this.selectedMessages);
toaster.toastOperation(op);
this.setEditMode(false);
}.bind(this)
},
{ // Cancel
id: 'msg-delete-cancel',
handler: null
}
);
},
onStarMessages: function() {
var op = this.model.api.markMessagesStarred(this.selectedMessages,
this.setAsStarred);
this.setEditMode(false);
toaster.toastOperation(op);
},
onMarkMessagesRead: function() {
var op = this.model.api.markMessagesRead(this.selectedMessages,
this.setAsRead);
this.setEditMode(false);
toaster.toastOperation(op);
},
onMoveMessages: function() {
cards.folderSelector(this.model, function(folder) {
var op = this.model.api.moveMessages(this.selectedMessages, folder);
toaster.toastOperation(op);
this.setEditMode(false);
}.bind(this), function(folder) {
return folder.isValidMoveTarget;
});
}
};
});