From 7a0a75a8376ee4f543578c5599164abc8b4bd1c0 Mon Sep 17 00:00:00 2001
From: Christoph Wurst <christoph@winzerhof-wurst.at>
Date: Thu, 1 Feb 2018 16:19:40 +0100
Subject: [PATCH] Remove session storage cache

* Only used for HTML bodies, which are cached on HTTP level anyway
* Preloading of messages was broken and has to be re-evaluated
* Made the app unusable with large mailboxes

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
---
 js/app.js                              |   2 -
 js/cache.js                            | 160 -------------------------
 js/controller/foldercontroller.js      |  24 ----
 js/controller/messagecontroller.js     |   2 -
 js/service/accountservice.js           |   7 +-
 js/service/messageservice.js           |  44 -------
 js/tests/integration/app_start_spec.js |   5 +-
 7 files changed, 2 insertions(+), 242 deletions(-)
 delete mode 100644 js/cache.js

diff --git a/js/app.js b/js/app.js
index 89a363ddc..e47868ffb 100644
--- a/js/app.js
+++ b/js/app.js
@@ -30,7 +30,6 @@ define(function(require) {
 	var Marionette = require('backbone.marionette');
 	var OC = require('OC');
 	var AppView = require('views/appview');
-	var Cache = require('cache');
 	var Radio = require('radio');
 	var Router = require('router');
 	var AccountController = require('controller/accountcontroller');
@@ -101,7 +100,6 @@ define(function(require) {
 		this._useExternalAvatars = $('#external-avatars').val() === 'true';
 
 		this.view = new AppView();
-		Cache.init();
 
 		Radio.ui.trigger('content:loading', t('mail', 'Loading accounts'));
 
diff --git a/js/cache.js b/js/cache.js
deleted file mode 100644
index f19f83e21..000000000
--- a/js/cache.js
+++ /dev/null
@@ -1,160 +0,0 @@
-/**
- * Mail
- *
- * This file is licensed under the Affero General Public License version 3 or
- * later. See the COPYING file.
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @copyright Christoph Wurst 2015, 2016
- */
-
-define(function(require) {
-	'use strict';
-
-	var _ = require('underscore');
-	var $ = require('jquery');
-	var storage = require('js-storage').localStorage;
-	var Account = require('models/account');
-
-	var MessageCache = {
-		/**
-		 * @param {Account} account
-		 * @returns {string}
-		 */
-		getAccountPath: function(account) {
-			return ['messages', account.get('accountId').toString()].join('.');
-		},
-		/**
-		 * @param {Account} account
-		 * @param {Folder} folder
-		 * @returns {string}
-		 */
-		getFolderPath: function(account, folder) {
-			return [this.getAccountPath(account), folder.get('id').toString()].join('.');
-		},
-		/**
-		 * @param {Account} account
-		 * @param {Folder} folder
-		 * @param {number} messageId
-		 * @returns {string}
-		 */
-		getMessagePath: function(account, folder, messageId) {
-			return [this.getFolderPath(account, folder), messageId.toString()].join('.');
-		}
-	};
-
-	function init() {
-		console.log('initializing cache…');
-		var installedVersion = $('#config-installed-version').val();
-		if (storage.isSet('mail-app-version')) {
-			var cachedVersion = storage.get('mail-app-version');
-			if (cachedVersion !== installedVersion) {
-				console.log('clearing cache because app version has changed');
-				storage.removeAll();
-			}
-		} else {
-			// Could be an old version -> clear data
-			storage.removeAll();
-		}
-		storage.set('mail-app-version', installedVersion);
-	}
-
-	/**
-	 * @param {AccountsCollection} accounts
-	 */
-	function cleanUp(accounts) {
-		var activeAccounts = accounts.map(function(account) {
-			return account.get('accountId');
-		});
-		_.each(storage.get('messages'), function(account, accountId) {
-			var isActive = _.any(activeAccounts, function(a) {
-				return a === parseInt(accountId);
-			});
-			if (!isActive) {
-				// Account does not exist anymore -> remove it
-				storage.remove('messages.' + accountId);
-			}
-		});
-	}
-
-	/**
-	 * @param {Account} account
-	 * @param {Folder} folder
-	 * @param {Message} messageId
-	 */
-	function getMessage(account, folder, messageId) {
-		var path = MessageCache.getMessagePath(account, folder, messageId);
-		if (storage.isSet(path)) {
-			var message = storage.get(path);
-			// Update the timestamp
-			addMessage(account, folder, message);
-			return message;
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * @param {Account} account
-	 * @param {Folder} folder
-	 * @param {Message} message
-	 */
-	function addMessage(account, folder, message) {
-		var path = MessageCache.getMessagePath(account, folder, message.id);
-		// Save the message to local storage
-		storage.set(path, message);
-	}
-
-	/**
-	 * @param {Account} account
-	 * @param {Folder} folder
-	 * @param {Message} messages
-	 */
-	function addMessages(account, folder, messages) {
-		_.each(messages, function(message) {
-			addMessage(account, folder, message);
-		});
-	}
-
-	/**
-	 * @param {Account} account
-	 * @param {Folder} folder
-	 * @param {number} messageId
-	 */
-	function removeMessage(account, folder, messageId) {
-		var message = getMessage(account, folder, messageId);
-		if (message) {
-			// message exists in cache -> remove it
-			storage.remove(MessageCache.getMessagePath(account, folder, messageId));
-		}
-	}
-
-	/**
-	 * @param {Account} account
-	 */
-	function removeAccount(account) {
-		// Remove cached messages
-		var path = MessageCache.getAccountPath(account);
-		if (storage.isSet(path)) {
-			storage.remove(path);
-		}
-
-		// Unified inbox hack
-		if (account.get('accountId') !== -1) {
-			// Make sure unified inbox cache is cleared to prevent
-			// old message showing up on the next load
-			removeAccount(new Account({accountId: -1}));
-		}
-		// End unified inbox hack
-	}
-
-	return {
-		init: init,
-		cleanUp: cleanUp,
-		getMessage: getMessage,
-		addMessage: addMessage,
-		addMessages: addMessages,
-		removeMessage: removeMessage,
-		removeAccount: removeAccount
-	};
-});
diff --git a/js/controller/foldercontroller.js b/js/controller/foldercontroller.js
index 1a0d60467..5799ceb84 100644
--- a/js/controller/foldercontroller.js
+++ b/js/controller/foldercontroller.js
@@ -27,7 +27,6 @@ define(function(require) {
 	var Radio = require('radio');
 	var ErrorMessageFactory = require('util/errormessagefactory');
 
-	Radio.message.on('fetch:bodies', fetchBodies);
 	Radio.folder.reply('message:delete', deleteMessage);
 
 	/**
@@ -79,8 +78,6 @@ define(function(require) {
 				$('#mail_new_message').prop('disabled', false);
 
 				if (messages.length > 0) {
-					// Fetch first 10 messages in background
-					Radio.message.trigger('fetch:bodies', account, folder, messages.slice(0, 10));
 					if (openFirstMessage) {
 						var message = messages.first();
 						Radio.message.trigger('load', message.folder.account, message.folder, message);
@@ -146,27 +143,6 @@ define(function(require) {
 		});
 	}
 
-	/**
-	 * Fetch and cache messages in the background
-	 *
-	 * The message is only fetched if it has not been cached already
-	 *
-	 * @param {Account} account
-	 * @param {Folder} folder
-	 * @param {Message[]} messages
-	 */
-	function fetchBodies(account, folder, messages) {
-		if (messages.length > 0) {
-			var ids = _.map(messages, function(message) {
-				return message.get('id');
-			});
-			Radio.message.request('bodies', account, folder, ids).
-				then(function(messages) {
-					require('cache').addMessages(account, folder, messages);
-				}, console.error.bind(this));
-		}
-	}
-
 	/**
 	 * @param {Folder} folder
 	 * @param {Folder} currentFolder
diff --git a/js/controller/messagecontroller.js b/js/controller/messagecontroller.js
index d239eddf7..1ad4424f7 100644
--- a/js/controller/messagecontroller.js
+++ b/js/controller/messagecontroller.js
@@ -80,8 +80,6 @@ define(function(require) {
 			if (draft) {
 				Radio.ui.trigger('composer:show', messageBody, true);
 			} else {
-				// TODO: ideally this should be handled in messageservice.js
-				require('cache').addMessage(account, folder, messageBody);
 				Radio.ui.trigger('message:show', message, messageBody);
 			}
 		}, function() {
diff --git a/js/service/accountservice.js b/js/service/accountservice.js
index b53482d32..955456129 100644
--- a/js/service/accountservice.js
+++ b/js/service/accountservice.js
@@ -82,8 +82,6 @@ define(function(require) {
 	 */
 	function getAccountEntities() {
 		return loadAccountData().then(function(accounts) {
-			require('cache').cleanUp(accounts);
-
 			if (accounts.length > 1) {
 				accounts.add({
 					accountId: -1,
@@ -108,10 +106,7 @@ define(function(require) {
 
 		return Promise.resolve($.ajax(url, {
 			type: 'DELETE'
-		})).then(function() {
-			// Delete cached message lists
-			require('cache').removeAccount(account);
-		});
+		}));
 	}
 	
 	/**
diff --git a/js/service/messageservice.js b/js/service/messageservice.js
index a5dd43e68..389214906 100644
--- a/js/service/messageservice.js
+++ b/js/service/messageservice.js
@@ -30,7 +30,6 @@ define(function(require) {
 	Radio.message.reply('entities', getMessageEntities);
 	Radio.message.reply('next-page', getNextMessagePage);
 	Radio.message.reply('entity', getMessageEntity);
-	Radio.message.reply('bodies', fetchMessageBodies);
 	Radio.message.reply('flag', flagMessage);
 	Radio.message.reply('move', moveMessage);
 	Radio.message.reply('send', sendMessage);
@@ -257,14 +256,6 @@ define(function(require) {
 			messageId: messageId
 		});
 
-		// Load cached version if available
-		var message = require('cache').getMessage(account,
-			folder,
-			messageId);
-		if (message) {
-			return Promise.resolve(message);
-		}
-
 		return new Promise(function(resolve, reject) {
 			$.ajax(url, {
 				type: 'GET',
@@ -279,41 +270,6 @@ define(function(require) {
 		});
 	}
 
-	/**
-	 * @param {Account} account
-	 * @param {Folder} folder
-	 * @param {array} messageIds
-	 * @returns {Promise}
-	 */
-	function fetchMessageBodies(account, folder, messageIds) {
-		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);
-			}
-		});
-
-		return new Promise(function(resolve, reject) {
-			if (uncachedIds.length > 0) {
-				var Ids = uncachedIds.join(',');
-				var url = OC.generateUrl('apps/mail/api/accounts/{accountId}/folders/{folderId}/messages?ids={ids}', {
-					accountId: account.get('accountId'),
-					folderId: folder.get('id'),
-					ids: Ids
-				});
-				return Promise.resolve($.ajax(url, {
-					type: 'GET'
-				}));
-			}
-			reject();
-		});
-	}
-
 	/**
 	 * @param {Account} account
 	 * @param {Folder} folder
diff --git a/js/tests/integration/app_start_spec.js b/js/tests/integration/app_start_spec.js
index f8f8d22a9..12b214bed 100644
--- a/js/tests/integration/app_start_spec.js
+++ b/js/tests/integration/app_start_spec.js
@@ -22,12 +22,11 @@
 define([
 	'jquery',
 	'app',
-	'cache',
 	'radio',
 	'backbone',
 	'controller/accountcontroller',
 	'models/accountcollection'
-], function($, Mail, Cache, Radio, Backbone, AccountController,
+], function($, Mail, Radio, Backbone, AccountController,
 		AccountCollection) {
 	describe('App', function() {
 
@@ -70,7 +69,6 @@ define([
 				resolve = res;
 			});
 
-			spyOn(Cache, 'init');
 			spyOn(Radio.ui, 'trigger');
 			spyOn(Backbone.history, 'start');
 			spyOn(AccountController, 'loadAccounts').and.callFake(function() {
@@ -84,7 +82,6 @@ define([
 			// Let's go…
 			Mail.start();
 
-			expect(Cache.init).toHaveBeenCalled();
 			expect(Radio.ui.trigger).toHaveBeenCalledWith('content:loading', 'Loading accounts');
 
 			var accounts = new AccountCollection([
-- 
GitLab