Beispiel #1
0
		templateContext: function() {
			var app = require('app');
			return {
				addAccountUrl: OC.generateUrl('apps/mail/#setup'),
				useExternalAvatars: app.getUseExternalAvatars(),
				keyboardShortcutUrl: OC.generateUrl('apps/mail/#shortcuts')
			};
		},
Beispiel #2
0
	/**
	 * @param {Account} account
	 * @param {Folder} folder
	 * @param {number} messageId
	 * @param {number} attachmentId
	 * @param {string} path
	 * @returns {Promise}
	 */
	function saveToFiles(account, folder, messageId, attachmentId, path) {
		var defer = $.Deferred();
		var url = OC.generateUrl(
			'apps/mail/accounts/{accountId}/' +
			'folders/{folderId}/messages/{messageId}/' +
			'attachment/{attachmentId}', {
				accountId: account.get('accountId'),
				folderId: folder.get('id'),
				messageId: messageId,
				attachmentId: attachmentId
			});

		var options = {
			data: {
				targetPath: path
			},
			type: 'POST',
			success: function() {
				defer.resolve();
			},
			error: function() {
				defer.reject();
			}
		};

		$.ajax(url, options);
		return defer.promise();
	}
Beispiel #3
0
define(function(require) {
	'use strict';

	var Backbone = require('backbone');
	var FolderCollection = require('models/foldercollection');
	var OC = require('OC');

	/**
	 * @class Account
	 */
	var Account = Backbone.Model.extend({
		defaults: {
			folders: []
		},
		idAttribute: 'accountId',
		url: OC.generateUrl('apps/mail/accounts'),
		initialize: function() {
			this.set('folders', new FolderCollection(this.get('folders')));
		},
		toJSON: function() {
			var data = Backbone.Model.prototype.toJSON.call(this);
			if (data.folders && data.folders.toJSON) {
				data.folders = data.folders.toJSON();
			}
			if (!data.id) {
				data.id = this.cid;
			}
			return data;
		}
	});

	return Account;
});
Beispiel #4
0
		flagMessage: function(flag, value) {
			var messageId = this.id;
			var _this = this;
			_this.get('flags').set(flag, value);

			var flags = [flag, value];
			$.ajax(
				OC.generateUrl('apps/mail/accounts/{accountId}/folders/{folderId}/messages/{messageId}/flags',
					{
						accountId: require('state').currentAccount.get('accountId'),
						folderId: require('state').currentFolder.get('id'),
						messageId: messageId
					}), {
				data: {
					flags: _.object([flags])
				},
				type: 'PUT',
				success: function() {
				},
				error: function() {
					Radio.ui.trigger('error:show', t('mail', 'Message could not be starred. Please try again.'));
					_this.get('flags').set(flag, !value);
				}
			});
		}
Beispiel #5
0
	/**
	 * @param {Account} account
	 * @param {Folder} folder
	 * @param {array} messageIds
	 * @param {object} options
	 * @returns {undefined}
	 */
	function fetchMessages(account, folder, messageIds, options) {
		options = options || {};
		var defaults = {
			onSuccess: function() {
			},
			onError: function() {
			}
		};
		_.defaults(options, defaults);

		var cachedMessages = [];
		var uncachedIds = [];
		_.each(messageIds, function(messageId) {
			var message = require('cache').getMessage(account, folder, messageId);
			if (message) {
				cachedMessages.push(message);
			} else {
				uncachedIds.push(messageId);
			}
		});

		if (uncachedIds.length > 0) {
			var Ids = uncachedIds.join(',');
			var url = OC.generateUrl('apps/mail/accounts/{accountId}/folders/{folderId}/messages?ids={ids}', {
				accountId: account.get('accountId'),
				folderId: folder.get('id'),
				ids: Ids
			});
			$.ajax(url, {
				type: 'GET',
				success: options.onSuccess,
				error: options.onError
			});
		}
	}
	/**
	 * @param {File} file
	 * @param {LocalAttachment} localAttachment
	 * @returns {Promise}
	 */
	function uploadLocalAttachment(file, localAttachment) {
		var fd = new FormData();
		fd.append('attachment', file);

		var progressCallback = localAttachment.onProgress;
		var url = OC.generateUrl('/apps/mail/api/attachments');

		return Promise.resolve($.ajax({
			url: url,
			type: 'POST',
			xhr: function() {
				var customXhr = $.ajaxSettings.xhr();
				// save the xhr into the model in order to :
				//  - distinguish upload and nextcloud file attachments
				//  - keep the upload status for later use
				localAttachment.set('uploadRequest', customXhr);
				// and start the request
				if (customXhr.upload && _.isFunction(progressCallback)) {
					customXhr.upload.addEventListener(
						'progress',
						progressCallback.bind(localAttachment),
						false);
				}
				return customXhr;
			},
			data: fd,
			processData: false,
			contentType: false
		})).then(function(data) {
			return data.id;
		});
	}
Beispiel #7
0
	/**
	 * @param {Account} account
	 * @param {Folder} folder
	 * @param {array} messageIds
	 * @returns {undefined}
	 */
	function fetchMessageBodies(account, folder, messageIds) {
		var defer = $.Deferred();

		var cachedMessages = [];
		var uncachedIds = [];
		_.each(messageIds, function(messageId) {
			var message = require('cache').getMessage(account, folder, messageId);
			if (message) {
				cachedMessages.push(message);
			} else {
				uncachedIds.push(messageId);
			}
		});

		if (uncachedIds.length > 0) {
			var Ids = uncachedIds.join(',');
			var url = OC.generateUrl('apps/mail/accounts/{accountId}/folders/{folderId}/messages?ids={ids}', {
				accountId: account.get('accountId'),
				folderId: folder.get('id'),
				ids: Ids
			});
			$.ajax(url, {
				type: 'GET',
				success: function(data) {
					defer.resolve(data);
				},
				error: function() {
					defer.reject();
				}
			});
		}

		return defer.promise();
	}
Beispiel #8
0
		deleteMessage: function(event) {
			event.stopPropagation();
			var thisModel = this.model;
			this.ui.iconDelete.removeClass('icon-delete').addClass('icon-loading');
			$('.tipsy').remove();

			thisModel.get('flags').set('unseen', false);
			var folder = require('state').currentFolder;
			var count = folder.get('total');
			folder.set('total', count - 1);

			this.$el.addClass('transparency').slideUp(function() {
				$('.tipsy').remove();
				$('.tooltip').remove();

				var thisModelCollection = thisModel.collection;
				var index = thisModelCollection.indexOf(thisModel);
				var nextMessage = thisModelCollection.at(index - 1);
				if (!nextMessage) {
					nextMessage = thisModelCollection.at(index + 1);
				}
				thisModelCollection.remove(thisModel);
				if (require('state').currentMessageId === thisModel.id) {
					if (nextMessage) {
						var account = require('state').currentAccount;
						var folder = require('state').currentFolder;
						var messageId = nextMessage.id; //TODO: backbone property
						Radio.ui.trigger('message:load', account, folder, messageId);
					}
				}
				// manually trigger mouseover event for current mouse position
				// in order to create a tipsy for the next message if needed
				if (event.clientX) {
					$(document.elementFromPoint(event.clientX, event.clientY)).trigger('mouseover');
				}
			});

			// really delete the message
			$.ajax(
				OC.generateUrl('apps/mail/accounts/{accountId}/folders/{folderId}/messages/{messageId}',
					{
						accountId: require('state').currentAccount.get('accountId'),
						folderId: require('state').currentFolder.get('id'),
						messageId: thisModel.id
					}), {
				data: {},
				type: 'DELETE',
				success: function() {
					var cache = require('cache');
					var state = require('state');
					cache.removeMessage(state.currentAccount, state.currentFolder, thisModel.id);
				},
				error: function() {
					Radio.ui.trigger('error:show', t('mail', 'Error while deleting message.'));
				}
			});
		}
Beispiel #9
0
	/**
	 * @param {Account} account
	 * @param {Folder} folder
	 * @param {object} options
	 * @returns {undefined}
	 */
	function fetchMessageList(account, folder, options) {
		options = options || {};
		var defaults = {
			cache: false,
			replace: false, // Replace cached folder list
			force: false,
			onSuccess: function() {
			},
			onError: function() {
			},
			onComplete: function() {
			}
		};
		_.defaults(options, defaults);

		// Abort previous requests
		if (messageListXhr !== null) {
			messageListXhr.abort();
		}

		if (options.cache) {
			// Load cached version if available
			var messageList = require('cache').getMessageList(account, folder);
			if (!options.force && messageList) {
				options.onSuccess(messageList, true);
				options.onComplete();
				return;
			}
		}

		var url = OC.generateUrl('apps/mail/accounts/{accountId}/folders/{folderId}/messages',
			{
				accountId: account.get('accountId'),
				folderId: folder.get('id')
			});
		messageListXhr = $.ajax(url,
			{
				data: {
					from: options.from,
					to: options.to,
					filter: options.filter
				},
				success: function(messages) {
					if (options.replace || options.cache) {
						require('cache').addMessageList(account, folder, messages);
					}
					options.onSuccess(messages, false);
				},
				error: function(error, status) {
					if (status !== 'abort') {
						options.onError(error);
					}
				},
				complete: options.onComplete
			});
	}
Beispiel #10
0
	/**
	 * @param {Account} account
	 * @param aliasId
	 * @returns {Promise}
	 */
	function deleteAlias(account, aliasId) {
		var url = OC.generateUrl('/apps/mail/accounts/{id}/aliases/{aliasId}', {
			id: account.get('accountId'),
			aliasId: aliasId
		});
		var data = {
			type: 'DELETE'
		};
		return Promise.resolve($.ajax(url, data));
	}
Beispiel #11
0
		accounts.each(function(account) {
			var folders = account.get('folders');

			var url = OC.generateUrl('apps/mail/accounts/{id}/folders/detectChanges',
				{
					id: account.get('accountId')
				});
			$.ajax(url, {
				data: JSON.stringify({folders: folders.toJSON()}),
				contentType: 'application/json; charset=utf-8',
				dataType: 'json',
				type: 'POST',
				success: function(jsondata) {
					_.each(jsondata, function(changes) {
						// send notification
						if (changes.newUnReadCounter > 0) {
							Radio.notification.trigger(
								'favicon:change',
								OC.filePath(
									'mail',
									'img',
									'favicon-notification.png'));
							// only show one notification
							if (State.accounts.length === 1 || account.get('accountId') === -1) {
								showMailNotification(account.get('email'), changes);
							}
						}

						// update folder status
						var changedAccount = accounts.get(changes.accountId);
						var localFolder = folders.get(changes.id);
						localFolder.set('uidvalidity', changes.uidvalidity);
						localFolder.set('uidnext', changes.uidnext);
						localFolder.set('unseen', changes.unseen);
						localFolder.set('total', changes.total);

						// reload if current selected folder has changed
						if (State.currentAccount === changedAccount &&
							State.currentFolder.get('id') === changes.id) {
							Radio.ui.request('messagesview:collection').
								add(changes.messages);
						}

						// Save new messages to the cached message list
						var cachedList = Cache.getMessageList(changedAccount, localFolder);
						if (cachedList) {
							cachedList = cachedList.concat(changes.messages);
							Cache.addMessageList(changedAccount, localFolder, cachedList);
						}

						State.folderView.updateTitle();
					});
				}
			});
		});
Beispiel #12
0
	/**
	 * @param {Account} account
	 * @returns {Promise}
	 */
	function deleteAccount(account) {
		var url = OC.generateUrl('/apps/mail/accounts/{accountId}', {
			accountId: account.get('accountId')
		});

		return Promise.resolve($.ajax(url, {
			type: 'DELETE'
		})).then(function() {
			// Delete cached message lists
			require('cache').removeAccount(account);
		});
	}
Beispiel #13
0
		registerProtocolHandler: function() {
			if (window.navigator.registerProtocolHandler) {
				var url = window.location.protocol + '//' +
					window.location.host +
					OC.generateUrl('apps/mail/compose?uri=%s');
				try {
					window.navigator
						.registerProtocolHandler('mailto', url, 'ownCloud Mail');
				} catch (e) {
				}
			}
		},
Beispiel #14
0
			function(path) {
				// Loading feedback
				var saveToFilesBtnSelector = '.attachment-save-to-cloud';
				if (typeof attachmentId !== 'undefined') {
					saveToFilesBtnSelector = 'li[data-attachment-id="' +
						attachmentId + '"] ' + saveToFilesBtnSelector;
				}
				$(saveToFilesBtnSelector)
					.removeClass('icon-folder')
					.addClass('icon-loading-small')
					.prop('disabled', true);

				$.ajax(
					OC.generateUrl(
						'apps/mail/accounts/{accountId}/' +
						'folders/{folderId}/messages/{messageId}/' +
						'attachment/{attachmentId}',
						{
							accountId: require('state').currentAccount.get('accountId'),
							folderId: require('state').currentFolder.get('id'),
							messageId: messageId,
							attachmentId: attachmentId
						}), {
					data: {
						targetPath: path
					},
					type: 'POST',
					success: function() {
						if (typeof attachmentId === 'undefined') {
							Radio.ui.trigger('error:show', t('mail', 'Attachments saved to Files.'));
						} else {
							Radio.ui.trigger('error:show', t('mail', 'Attachment saved to Files.'));
						}
					},
					error: function() {
						if (typeof attachmentId === 'undefined') {
							Radio.ui.trigger('error:show', t('mail', 'Error while saving attachments to Files.'));
						} else {
							Radio.ui.trigger('error:show', t('mail', 'Error while saving attachment to Files.'));
						}
					},
					complete: function() {
						// Remove loading feedback again
						$('.attachment-save-to-cloud')
							.removeClass('icon-loading-small')
							.addClass('icon-folder')
							.prop('disabled', false);
					}
				});
			},
Beispiel #15
0
	/**
	 * @param {Account} account
	 * @param alias
	 * @returns {Promise}
	 */
	function saveAlias(account, alias) {
		var url = OC.generateUrl('/apps/mail/accounts/{id}/folders', {
			id: account.get('accountId')
		});
		var data = {
			type: 'POST',
			data: {
				accountId: account.get('accountId'),
				alias: alias.alias,
				aliasName: alias.name
			}
		};
		return Promise.resolve($.ajax(url, data));
	}
Beispiel #16
0
		return new Promise(function(resolve, reject) {
			$.ajax(OC.generateUrl('apps/mail/accounts'), {
				data: config,
				type: 'POST',
				success: function() {
					resolve();
				},
				error: function(jqXHR, textStatus, errorThrown) {
					switch (jqXHR.status) {
						case 400:
							var response = JSON.parse(jqXHR.responseText);
							reject(response.message);
							break;
						default:
							var error = errorThrown || textStatus || t('mail', 'Unknown error');
							reject(t('mail', 'Error while creating an account: ' + error));
					}
				}
			});
		});
Beispiel #17
0
	function getFolderEntities(accountId) {
		var defer = $.Deferred();

		var url = OC.generateUrl('apps/mail/accounts/{accountId}/folders',
			{
				accountId: accountId
			});

		var promise = $.get(url);

		promise.done(function(data) {
			defer.resolve(data);
		});

		promise.fail(function() {
			defer.reject();
		});
		// TODO: handle account fetching error
		return defer.promise();
	}
Beispiel #18
0
	/**
	 * @param {Account} account
	 * @param {Folder} folder
	 * @param {number} messageId
	 * @param {object} options
	 * @returns {Promise}
	 */
	function getMessageEntity(account, folder, messageId, options) {
		options = options || {};
		var defaults = {
			backgroundMode: false
		};
		_.defaults(options, defaults);

		var defer = $.Deferred();

		// Load cached version if available
		var message = require('cache').getMessage(account,
			folder,
			messageId);
		if (message) {
			defer.resolve(message);
			return defer.promise();
		}

		var url = OC.generateUrl('apps/mail/accounts/{accountId}/folders/{folderId}/messages/{messageId}', {
			accountId: account.get('accountId'),
			folderId: folder.get('id'),
			messageId: messageId
		});
		var xhr = $.ajax(url, {
			type: 'GET',
			success: function(message) {
				defer.resolve(message);
			},
			error: function(jqXHR, textStatus) {
				if (textStatus !== 'abort') {
					defer.reject();
				}
			}
		});
		if (!options.backgroundMode) {
			// Save xhr to allow aborting unneeded requests
			require('state').messageLoading = xhr;
		}

		return defer.promise();
	}
Beispiel #19
0
	/**
	 * @param {Message} message
	 * @param {number} attachmentId
	 * @param {string} path
	 * @returns {Promise}
	 */
	function saveToFiles(message, attachmentId, path) {
		attachmentId = attachmentId || 0;
		var url = OC.generateUrl(
			'apps/mail/api/accounts/{accountId}/' +
			'folders/{folderId}/messages/{messageId}/' +
			'attachment/{attachmentId}', {
				accountId: message.folder.account.get('accountId'),
				folderId: message.folder.get('id'),
				messageId: message.get('id'),
				attachmentId: attachmentId
			});

		var options = {
			data: {
				targetPath: path
			},
			type: 'POST'
		};

		return Promise.resolve($.ajax(url, options));
	}
Beispiel #20
0
	/**
	 * @param {Account} account
	 * @param {object} message
	 * @param {object} options
	 * @returns {undefined}
	 */
	function sendMessage(account, message, options) {
		var defer = $.Deferred();

		var defaultOptions = {
			draftUID: null
		};
		_.defaults(options, defaultOptions);
		var url = OC.generateUrl('/apps/mail/accounts/{id}/send', {
			id: account.get('id')
		});
		var data = {
			type: 'POST',
			success: function(data) {
				if (!_.isNull(options.messageId)) {
					// Reply -> flag message as replied
					Radio.ui.trigger('messagesview:messageflag:set', options.messageId, 'answered', true);
				}

				defer.resolve(data);
			},
			error: function(xhr) {
				defer.reject(xhr);
			},
			data: {
				to: message.to,
				cc: message.cc,
				bcc: message.bcc,
				subject: message.subject,
				body: message.body,
				type: message.type,
				attachments: message.attachments,
				folderId: options.folder ? options.folder.get('id') : null,
				messageId: options.messageId,
				draftUID: options.draftUID
			}
		};
		$.ajax(url, data);

		return defer.promise();
	}
Beispiel #21
0
		onDelete: function(e) {
			e.stopPropagation();

			this.ui.deleteButton.removeClass('icon-delete').addClass('icon-loading-small');

			var account = this.model;

			$.ajax(OC.generateUrl('/apps/mail/accounts/{accountId}'), {
				data: {accountId: account.get('accountId')},
				type: 'DELETE',
				success: function() {
					// Delete cached message lists
					require('cache').removeAccount(account);

					// reload the complete page
					// TODO should only reload the app nav/content
					window.location.reload();
				},
				error: function() {
					OC.Notification.show(t('mail', 'Error while deleting account.'));
				}
			});
		},
Beispiel #22
0
	/**
	 * @param {Account} account
	 * @param {Folder} folder
	 * @param {number} messageId
	 * @param {object} options
	 * @returns {undefined}
	 */
	function fetchMessage(account, folder, messageId, options) {
		options = options || {};
		var defaults = {
			onSuccess: function() {
			},
			onError: function() {
			},
			backgroundMode: false
		};
		_.defaults(options, defaults);

		// Load cached version if available
		var message = require('cache').getMessage(account,
			folder,
			messageId);
		if (message) {
			options.onSuccess(message);
			return;
		}

		var xhr = $.ajax(
			OC.generateUrl('apps/mail/accounts/{accountId}/folders/{folderId}/messages/{messageId}',
				{
					accountId: account.get('accountId'),
					folderId: folder.get('id'),
					messageId: messageId
				}), {
			data: {},
			type: 'GET',
			success: options.onSuccess,
			error: options.onError
		});
		if (!options.backgroundMode) {
			// Save xhr to allow aborting unneded requests
			require('state').messageLoading = xhr;
		}
	}
Beispiel #23
0
		templateHelpers: function() {
			return {
				addAccountUrl: OC.generateUrl('apps/mail/#setup')
			};
		},
Beispiel #24
0
		url: function() {
			return OC.generateUrl('apps/mail/api/accounts');
		},
Beispiel #25
0
	/**
	 * @param {Account} account
	 * @param {object} message
	 * @param {object} options
	 * @returns {undefined}
	 */
	function saveDraft(account, message, options) {
		var defer = $.Deferred();

		var defaultOptions = {
			folder: null,
			messageId: null,
			draftUID: null
		};
		_.defaults(options, defaultOptions);

		// TODO: replace by Backbone model method
		function undefinedOrEmptyString(prop) {
			return prop === undefined || prop === '';
		}
		var emptyMessage = true;
		var propertiesToCheck = ['to', 'cc', 'bcc', 'subject', 'body'];
		_.each(propertiesToCheck, function(property) {
			if (!undefinedOrEmptyString(message[property])) {
				emptyMessage = false;
			}
		});
		// END TODO

		if (emptyMessage) {
			if (options.draftUID !== null) {
				// Message is empty + previous draft exists -> delete it
				var draftsFolder = account.get('specialFolders').drafts;
				var deleteUrl =
					OC.generateUrl('apps/mail/accounts/{accountId}/folders/{folderId}/messages/{messageId}', {
						accountId: account.get('accountId'),
						folderId: draftsFolder,
						messageId: options.draftUID
					});
				$.ajax(deleteUrl, {
					type: 'DELETE'
				});
			}
			options.success({
				uid: null
			});
		} else {
			var url = OC.generateUrl('/apps/mail/accounts/{id}/draft', {
				id: account.get('accountId')
			});
			var data = {
				type: 'POST',
				success: function(data) {
					if (options.draftUID !== null) {
						// update UID in message list
						var collection = Radio.ui.request('messagesview:collection');
						var message = collection.findWhere({id: options.draftUID});
						if (message) {
							message.set({id: data.uid});
							collection.set([message], {remove: false});
						}
					}
					defer.resolve(data);
				},
				error: function() {
					defer.reject();
				},
				data: {
					to: message.to,
					cc: message.cc,
					bcc: message.bcc,
					subject: message.subject,
					body: message.body,
					type: message.type,
					attachments: message.attachments,
					folderId: options.folder ? options.folder.get('id') : null,
					messageId: options.messageId,
					uid: options.draftUID
				}
			};
			$.ajax(url, data);

			return defer.promise();
		}
	}