Completed
Push — master ( 51b9e4...c7e97b )
by Rain
01:27
created

MessageUserStore.setMessageList   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
c 0
b 0
f 0
nc 6
nop 1
dl 0
loc 27
rs 6.7272
1
2
var
3
	_ = require('_'),
4
	ko = require('ko'),
5
	window = require('window'),
6
	$ = require('$'),
7
8
	kn = require('Knoin/Knoin'),
9
10
	Enums = require('Common/Enums'),
11
	Consts = require('Common/Consts'),
12
	Globals = require('Common/Globals'),
13
	Utils = require('Common/Utils'),
14
	Links = require('Common/Links'),
15
	Translator = require('Common/Translator'),
16
17
	Cache = require('Common/Cache'),
18
19
	AppStore = require('Stores/User/App'),
20
	FolderStore = require('Stores/User/Folder'),
21
	PgpStore = require('Stores/User/Pgp'),
22
	SettingsStore = require('Stores/User/Settings'),
23
24
	Remote = require('Remote/User/Ajax'),
25
26
	MessageModel = require('Model/Message').default,
27
	MessageHelper = require('Helper/Message');
28
29
/**
30
 * @constructor
31
 */
32
function MessageUserStore()
33
{
34
	this.staticMessage = new MessageModel();
35
36
	this.messageList = ko.observableArray([]).extend({'rateLimit': 0});
37
38
	this.messageListCount = ko.observable(0);
39
	this.messageListSearch = ko.observable('');
40
	this.messageListThreadUid = ko.observable('');
41
	this.messageListPage = ko.observable(1);
42
	this.messageListPageBeforeThread = ko.observable(1);
43
	this.messageListError = ko.observable('');
44
45
	this.messageListEndFolder = ko.observable('');
46
	this.messageListEndSearch = ko.observable('');
47
	this.messageListEndThreadUid = ko.observable('');
48
	this.messageListEndPage = ko.observable(1);
49
50
	this.messageListLoading = ko.observable(false);
51
	this.messageListIsNotCompleted = ko.observable(false);
52
	this.messageListCompleteLoadingThrottle = ko.observable(false).extend({'throttle': 200});
53
	this.messageListCompleteLoadingThrottleForAnimation = ko.observable(false).extend({'specialThrottle': 700});
54
55
	this.messageListDisableAutoSelect = ko.observable(false).extend({'falseTimeout': 500});
56
57
	this.selectorMessageSelected = ko.observable(null);
58
	this.selectorMessageFocused = ko.observable(null);
59
60
	// message viewer
61
	this.message = ko.observable(null);
62
63
	this.message.viewTrigger = ko.observable(false);
64
65
	this.messageError = ko.observable('');
66
67
	this.messageCurrentLoading = ko.observable(false);
68
69
	this.messageLoading = ko.computed(function() {
70
		return this.messageCurrentLoading();
71
	}, this);
72
73
	this.messageLoadingThrottle = ko.observable(false).extend({'throttle': Enums.Magics.Time50ms});
74
75
	this.messageFullScreenMode = ko.observable(false);
76
77
	this.messagesBodiesDom = ko.observable(null);
78
	this.messageActiveDom = ko.observable(null);
79
80
	this.computers();
81
	this.subscribers();
82
83
	this.onMessageResponse = _.bind(this.onMessageResponse, this);
84
85
	this.purgeMessageBodyCacheThrottle = _.throttle(this.purgeMessageBodyCache, Enums.Magics.Time30s);
86
}
87
88
MessageUserStore.prototype.computers = function()
89
{
90
	var self = this;
91
92
	this.messageListEndHash = ko.computed(function() {
93
		return this.messageListEndFolder() + '|' + this.messageListEndSearch() +
94
			'|' + this.messageListEndThreadUid() +
95
			'|' + this.messageListEndPage();
96
	}, this);
97
98
	this.messageListPageCount = ko.computed(function() {
99
		var iPage = window.Math.ceil(this.messageListCount() /
100
			SettingsStore.messagesPerPage());
101
		return 0 >= iPage ? 1 : iPage;
102
	}, this);
103
104
	this.mainMessageListSearch = ko.computed({
105
		'read': this.messageListSearch,
106
		'write': function(sValue) {
107
			kn.setHash(Links.mailBox(
108
				FolderStore.currentFolderFullNameHash(), 1,
109
				Utils.trim(sValue.toString()), self.messageListThreadUid()
110
			));
111
		},
112
		'owner': this
113
	});
114
115
	this.messageListCompleteLoading = ko.computed(function() {
116
		var
117
			bOne = this.messageListLoading(),
118
			bTwo = this.messageListIsNotCompleted();
119
		return bOne || bTwo;
120
	}, this);
121
122
	this.isMessageSelected = ko.computed(function() {
123
		return null !== this.message();
124
	}, this);
125
126
	this.messageListChecked = ko.computed(function() {
127
		return _.filter(this.messageList(), function(oItem) {
128
			return oItem.checked();
129
		});
130
	}, this).extend({'rateLimit': 0});
131
132
	this.hasCheckedMessages = ko.computed(function() {
133
		return 0 < this.messageListChecked().length;
134
	}, this).extend({'rateLimit': 0});
135
136
	this.messageListCheckedOrSelected = ko.computed(function() {
137
138
		var
139
			aChecked = this.messageListChecked(),
140
			oSelectedMessage = this.selectorMessageSelected();
141
142
		return _.union(aChecked, oSelectedMessage ? [oSelectedMessage] : []);
143
144
	}, this);
145
146
	this.messageListCheckedOrSelectedUidsWithSubMails = ko.computed(function() {
147
		var aList = [];
148
		_.each(this.messageListCheckedOrSelected(), function(oMessage) {
149
			if (oMessage)
150
			{
151
				aList.push(oMessage.uid);
152
				if (1 < oMessage.threadsLen())
153
				{
154
					aList = _.union(aList, oMessage.threads());
155
				}
156
			}
157
		});
158
		return aList;
159
	}, this);
160
};
161
162
MessageUserStore.prototype.subscribers = function()
163
{
164
	this.messageListCompleteLoading.subscribe(function(bValue) {
165
		bValue = !!bValue;
166
		this.messageListCompleteLoadingThrottle(bValue);
167
		this.messageListCompleteLoadingThrottleForAnimation(bValue);
168
	}, this);
169
170
	this.messageList.subscribe(_.debounce(function(aList) {
171
		_.each(aList, function(oItem) {
172
			if (oItem && oItem.newForAnimation())
173
			{
174
				oItem.newForAnimation(false);
175
			}
176
		});
177
	}, Enums.Magics.Time500ms));
178
179
	this.message.subscribe(function(oMessage) {
180
181
		if (oMessage)
182
		{
183
			if (Enums.Layout.NoPreview === SettingsStore.layout())
184
			{
185
				AppStore.focusedState(Enums.Focused.MessageView);
186
			}
187
		}
188
		else
189
		{
190
			AppStore.focusedState(Enums.Focused.MessageList);
191
192
			this.messageFullScreenMode(false);
193
			this.hideMessageBodies();
194
		}
195
196
	}, this);
197
198
	this.messageLoading.subscribe(function(bValue) {
199
		this.messageLoadingThrottle(bValue);
200
	}, this);
201
202
	this.messagesBodiesDom.subscribe(function(oDom) {
203
		if (oDom && !(oDom instanceof $))
204
		{
205
			this.messagesBodiesDom($(oDom));
206
		}
207
	}, this);
208
209
	this.messageListEndFolder.subscribe(function(sFolder) {
210
		var oMessage = this.message();
211
		if (oMessage && sFolder && sFolder !== oMessage.folderFullNameRaw)
212
		{
213
			this.message(null);
214
		}
215
	}, this);
216
};
217
218
MessageUserStore.prototype.purgeMessageBodyCache = function()
219
{
220
	var
221
		iCount = 0,
222
		oMessagesDom = null,
223
		iEnd = Globals.data.iMessageBodyCacheCount - Consts.MESSAGE_BODY_CACHE_LIMIT;
224
225
	if (0 < iEnd)
226
	{
227
		oMessagesDom = this.messagesBodiesDom();
228
		if (oMessagesDom)
229
		{
230
			oMessagesDom.find('.rl-cache-class').each(function() {
231
				var oItem = $(this);
232
				if (iEnd > oItem.data('rl-cache-count'))
233
				{
234
					oItem.addClass('rl-cache-purge');
235
					iCount += 1;
236
				}
237
			});
238
239
			if (0 < iCount)
240
			{
241
				_.delay(function() {
242
					oMessagesDom.find('.rl-cache-purge').remove();
243
				}, Enums.Magics.Time350ms);
244
			}
245
		}
246
	}
247
};
248
249
MessageUserStore.prototype.initUidNextAndNewMessages = function(sFolder, sUidNext, aNewMessages)
250
{
251
	if (Cache.getFolderInboxName() === sFolder && Utils.isNormal(sUidNext) && '' !== sUidNext)
252
	{
253
		if (Utils.isArray(aNewMessages) && 0 < aNewMessages.length)
254
		{
255
			var
256
				iIndex = 0,
257
				iLen = aNewMessages.length,
258
				NotificationStore = require('Stores/User/Notification');
259
260
			_.each(aNewMessages, function(oItem) {
261
				Cache.addNewMessageCache(sFolder, oItem.Uid);
262
			});
263
264
			NotificationStore.playSoundNotification();
265
266
			if (3 < iLen)
267
			{
268
				NotificationStore.displayDesktopNotification(
269
					Links.notificationMailIcon(),
270
					require('Stores/User/Account').email(),
271
					Translator.i18n('MESSAGE_LIST/NEW_MESSAGE_NOTIFICATION', {
272
						'COUNT': iLen
273
					}),
274
					{'Folder': '', 'Uid': ''}
275
				);
276
			}
277
			else
278
			{
279
				for (; iIndex < iLen; iIndex++)
280
				{
281
					NotificationStore.displayDesktopNotification(
282
						Links.notificationMailIcon(),
283
						MessageHelper.emailArrayToString(MessageHelper.emailArrayFromJson(aNewMessages[iIndex].From), false),
284
						aNewMessages[iIndex].Subject,
285
						{'Folder': aNewMessages[iIndex].Folder, 'Uid': aNewMessages[iIndex].Uid}
286
					);
287
				}
288
			}
289
		}
290
291
		Cache.setFolderUidNext(sFolder, sUidNext);
292
	}
293
};
294
295
MessageUserStore.prototype.hideMessageBodies = function()
296
{
297
	var oMessagesDom = this.messagesBodiesDom();
298
	if (oMessagesDom)
299
	{
300
		oMessagesDom.find('.b-text-part').hide();
301
	}
302
};
303
304
/**
305
 * @param {string} sFromFolderFullNameRaw
306
 * @param {Array} aUidForRemove
307
 * @param {string=} sToFolderFullNameRaw = ''
308
 * @param {bCopy=} bCopy = false
309
 */
310
MessageUserStore.prototype.removeMessagesFromList = function(
311
	sFromFolderFullNameRaw, aUidForRemove, sToFolderFullNameRaw, bCopy)
312
{
313
	sToFolderFullNameRaw = Utils.isNormal(sToFolderFullNameRaw) ? sToFolderFullNameRaw : '';
314
	bCopy = Utils.isUnd(bCopy) ? false : !!bCopy;
315
316
	aUidForRemove = _.map(aUidForRemove, function(mValue) {
317
		return Utils.pInt(mValue);
318
	});
319
320
	var
321
		self = this,
322
		iUnseenCount = 0,
323
		sTrashFolder = FolderStore.trashFolder(),
324
		sSpamFolder = FolderStore.spamFolder(),
325
		aMessageList = this.messageList(),
326
		oFromFolder = Cache.getFolderFromCacheList(sFromFolderFullNameRaw),
327
		oToFolder = '' === sToFolderFullNameRaw ? null : Cache.getFolderFromCacheList(sToFolderFullNameRaw || ''),
328
		sCurrentFolderFullNameRaw = FolderStore.currentFolderFullNameRaw(),
329
		oCurrentMessage = this.message(),
330
		aMessages = sCurrentFolderFullNameRaw === sFromFolderFullNameRaw ? _.filter(aMessageList, function(item) {
331
			return item && -1 < Utils.inArray(Utils.pInt(item.uid), aUidForRemove);
332
		}) : [];
333
334
	_.each(aMessages, function(item) {
335
		if (item && item.unseen())
336
		{
337
			iUnseenCount += 1;
338
		}
339
	});
340
341
	if (oFromFolder && !bCopy)
342
	{
343
		oFromFolder.messageCountAll(0 <= oFromFolder.messageCountAll() - aUidForRemove.length ?
344
			oFromFolder.messageCountAll() - aUidForRemove.length : 0);
345
346
		if (0 < iUnseenCount)
347
		{
348
			oFromFolder.messageCountUnread(0 <= oFromFolder.messageCountUnread() - iUnseenCount ?
349
				oFromFolder.messageCountUnread() - iUnseenCount : 0);
350
		}
351
	}
352
353
	if (oToFolder)
354
	{
355
		if (sTrashFolder === oToFolder.fullNameRaw || sSpamFolder === oToFolder.fullNameRaw)
356
		{
357
			iUnseenCount = 0;
358
		}
359
360
		oToFolder.messageCountAll(oToFolder.messageCountAll() + aUidForRemove.length);
361
		if (0 < iUnseenCount)
362
		{
363
			oToFolder.messageCountUnread(oToFolder.messageCountUnread() + iUnseenCount);
364
		}
365
366
		oToFolder.actionBlink(true);
367
	}
368
369
	if (0 < aMessages.length)
370
	{
371
		if (bCopy)
372
		{
373
			_.each(aMessages, function(item) {
374
				item.checked(false);
375
			});
376
		}
377
		else
378
		{
379
			this.messageListIsNotCompleted(true);
380
381
			_.each(aMessages, function(item) {
382
				if (oCurrentMessage && oCurrentMessage.hash === item.hash)
383
				{
384
					oCurrentMessage = null;
385
					self.message(null);
386
				}
387
388
				item.deleted(true);
389
			});
390
391
			_.delay(function() {
392
				_.each(aMessages, function(item) {
393
					self.messageList.remove(item);
394
				});
395
			}, Enums.Magics.Time350ms);
396
		}
397
	}
398
399
	if ('' !== sFromFolderFullNameRaw)
400
	{
401
		Cache.setFolderHash(sFromFolderFullNameRaw, '');
402
	}
403
404
	if ('' !== sToFolderFullNameRaw)
405
	{
406
		Cache.setFolderHash(sToFolderFullNameRaw, '');
407
	}
408
409
	if ('' !== this.messageListThreadUid())
410
	{
411
		aMessageList = this.messageList();
412
413
		if (aMessageList && 0 < aMessageList.length && !!_.find(aMessageList, function(item) {
414
			return !!(item && item.deleted() && item.uid === self.messageListThreadUid());
415
		}))
416
		{
417
			var oMessage = _.find(aMessageList, function(item) {
418
				return item && !item.deleted();
419
			});
420
421
			if (oMessage && this.messageListThreadUid() !== Utils.pString(oMessage.uid))
422
			{
423
				this.messageListThreadUid(Utils.pString(oMessage.uid));
424
425
				kn.setHash(Links.mailBox(
426
					FolderStore.currentFolderFullNameHash(),
427
					this.messageListPage(),
428
					this.messageListSearch(),
429
					this.messageListThreadUid()
430
				), true, true);
431
			}
432
			else if (!oMessage)
433
			{
434
				if (1 < this.messageListPage())
435
				{
436
					this.messageListPage(this.messageListPage() - 1);
437
438
					kn.setHash(Links.mailBox(
439
						FolderStore.currentFolderFullNameHash(),
440
						this.messageListPage(),
441
						this.messageListSearch(),
442
						this.messageListThreadUid()
443
					), true, true);
444
				}
445
				else
446
				{
447
					this.messageListThreadUid('');
448
449
					kn.setHash(Links.mailBox(
450
						FolderStore.currentFolderFullNameHash(),
451
						this.messageListPageBeforeThread(),
452
						this.messageListSearch()
453
					), true, true);
454
				}
455
			}
456
		}
457
	}
458
};
459
460
MessageUserStore.prototype.addBlockquoteSwitcherCallback = function()
461
{
462
	var $self = $(this);
463
	if ('' !== Utils.trim(($self.text())))
464
	{
465
		$self.addClass('rl-bq-switcher hidden-bq');
466
		$('<span class="rlBlockquoteSwitcher"><i class="icon-ellipsis" /></span>')
467
			.insertBefore($self)
468
			.on('click.rlBlockquoteSwitcher', function() {
469
				$self.toggleClass('hidden-bq');
470
				Utils.windowResize();
471
			})
472
			.after('<br />')
473
			.before('<br />');
474
	}
475
};
476
477
/**
478
 * @param {Object} oMessageTextBody
479
 */
480
MessageUserStore.prototype.initBlockquoteSwitcher = function(oMessageTextBody)
481
{
482
	if (oMessageTextBody)
483
	{
484
		var $oList = $('blockquote:not(.rl-bq-switcher)', oMessageTextBody).filter(function() {
485
			return 0 === $(this).parent().closest('blockquote', oMessageTextBody).length;
486
		});
487
488
		if ($oList && 0 < $oList.length)
489
		{
490
			$oList.each(this.addBlockquoteSwitcherCallback);
491
		}
492
	}
493
};
494
495
/**
496
 * @param {Object} oMessageTextBody
497
 */
498
MessageUserStore.prototype.initOpenPgpControls = function(oMessageTextBody, oMessage)
499
{
500
	if (oMessageTextBody && oMessageTextBody.find)
501
	{
502
		oMessageTextBody.find('.b-plain-openpgp:not(.inited)').each(function() {
503
			PgpStore.initMessageBodyControls($(this), oMessage);
504
		});
505
	}
506
};
507
508
MessageUserStore.prototype.setMessage = function(oData, bCached)
509
{
510
	var
511
		bNew = false,
512
		oBody = null,
513
		sId = '',
514
		sPlain = '',
515
		sResultHtml = '',
516
		bPgpSigned = false,
517
		oMessagesDom = this.messagesBodiesDom(),
518
		oSelectedMessage = this.selectorMessageSelected(),
519
		oMessage = this.message();
520
521
	if (oData && oMessage && oData.Result && 'Object/Message' === oData.Result['@Object'] &&
522
		oMessage.folderFullNameRaw === oData.Result.Folder)
523
	{
524
		var aThreads = oMessage.threads();
525
		if (oMessage.uid !== oData.Result.Uid && 1 < aThreads.length &&
526
			-1 < Utils.inArray(oData.Result.Uid, aThreads))
527
		{
528
			oMessage = MessageModel.newInstanceFromJson(oData.Result);
529
			if (oMessage)
530
			{
531
				oMessage.threads(aThreads);
532
				Cache.initMessageFlagsFromCache(oMessage);
533
534
				this.message(this.staticMessage.populateByMessageListItem(oMessage));
535
				oMessage = this.message();
536
537
				bNew = true;
538
			}
539
		}
540
541
		if (oMessage && oMessage.uid === oData.Result.Uid)
542
		{
543
			this.messageError('');
544
545
			oMessage.initUpdateByMessageJson(oData.Result);
546
			Cache.addRequestedMessage(oMessage.folderFullNameRaw, oMessage.uid);
547
548
			if (!bCached)
549
			{
550
				oMessage.initFlagsByJson(oData.Result);
551
			}
552
553
			oMessagesDom = oMessagesDom && oMessagesDom[0] ? oMessagesDom : null;
554
			if (oMessagesDom)
555
			{
556
				sId = 'rl-mgs-' + oMessage.hash.replace(/[^a-zA-Z0-9]/g, '');
557
558
				var oTextBody = oMessagesDom.find('#' + sId);
559
				if (!oTextBody || !oTextBody[0])
560
				{
561
					var bIsHtml = false;
1 ignored issue
show
Unused Code introduced by
The assignment to variable bIsHtml seems to be never used. Consider removing it.
Loading history...
562
					if (Utils.isNormal(oData.Result.Html) && '' !== oData.Result.Html)
563
					{
564
						bIsHtml = true;
565
						sResultHtml = oData.Result.Html.toString();
566
					}
567
					else if (Utils.isNormal(oData.Result.Plain) && '' !== oData.Result.Plain)
568
					{
569
						bIsHtml = false;
570
						sResultHtml = Utils.plainToHtml(oData.Result.Plain.toString(), false);
571
572
						if ((oMessage.isPgpSigned() || oMessage.isPgpEncrypted()) && require('Stores/User/Pgp').capaOpenPGP())
573
						{
574
							sPlain = Utils.pString(oData.Result.Plain);
575
576
							var bPgpEncrypted = (/---BEGIN PGP MESSAGE---/).test(sPlain);
577
							if (!bPgpEncrypted)
578
							{
579
								bPgpSigned = (/-----BEGIN PGP SIGNED MESSAGE-----/).test(sPlain) &&
580
									(/-----BEGIN PGP SIGNATURE-----/).test(sPlain);
581
							}
582
583
							Globals.$div.empty();
584
							if (bPgpSigned && oMessage.isPgpSigned())
585
							{
586
								sResultHtml =
587
									Globals.$div.append(
588
										$('<pre class="b-plain-openpgp signed"></pre>').text(sPlain)
589
									).html();
590
							}
591
							else if (bPgpEncrypted && oMessage.isPgpEncrypted())
592
							{
593
								sResultHtml =
594
									Globals.$div.append(
595
										$('<pre class="b-plain-openpgp encrypted"></pre>').text(sPlain)
596
									).html();
597
							}
598
							else
599
							{
600
								sResultHtml = '<pre>' + sResultHtml + '</pre>';
601
							}
602
603
							Globals.$div.empty();
604
605
							oMessage.isPgpSigned(bPgpSigned);
606
							oMessage.isPgpEncrypted(bPgpEncrypted);
607
						}
608
						else
609
						{
610
							sResultHtml = '<pre>' + sResultHtml + '</pre>';
611
						}
612
					}
613
					else
614
					{
615
						bIsHtml = false;
616
						sResultHtml = '<pre>' + sResultHtml + '</pre>';
617
					}
618
619
					Globals.data.iMessageBodyCacheCount += 1;
620
621
					oBody = $('<div id="' + sId + '" ></div>').hide().addClass('rl-cache-class');
622
					oBody.data('rl-cache-count', Globals.data.iMessageBodyCacheCount);
623
624
					oBody
625
						.html(Utils.findEmailAndLinks(sResultHtml))
626
						.addClass('b-text-part ' + (bIsHtml ? 'html' : 'plain'));
627
628
					oMessage.isHtml(!!bIsHtml);
629
					oMessage.hasImages(!!oData.Result.HasExternals);
630
631
					oMessage.body = oBody;
632
					if (oMessage.body)
633
					{
634
						oMessagesDom.append(oMessage.body);
635
					}
636
637
					oMessage.storeDataInDom();
638
639
					if (oData.Result.HasInternals)
640
					{
641
						oMessage.showInternalImages(true);
642
					}
643
644
					if (oMessage.hasImages() && SettingsStore.showImages())
645
					{
646
						oMessage.showExternalImages(true);
647
					}
648
649
					this.purgeMessageBodyCacheThrottle();
650
				}
651
				else
652
				{
653
					oMessage.body = oTextBody;
654
					if (oMessage.body)
655
					{
656
						Globals.data.iMessageBodyCacheCount += 1;
657
						oMessage.body.data('rl-cache-count', Globals.data.iMessageBodyCacheCount);
658
						oMessage.fetchDataFromDom();
659
					}
660
				}
661
662
				this.messageActiveDom(oMessage.body);
663
664
				this.hideMessageBodies();
665
666
				if (oBody)
667
				{
668
					this.initOpenPgpControls(oBody, oMessage);
669
670
					this.initBlockquoteSwitcher(oBody);
671
				}
672
673
				oMessage.body.show();
674
			}
675
676
			Cache.initMessageFlagsFromCache(oMessage);
677
			if (oMessage.unseen() || oMessage.hasUnseenSubMessage())
678
			{
679
				require('App/User').default.messageListAction(oMessage.folderFullNameRaw,
680
					oMessage.uid, Enums.MessageSetAction.SetSeen, [oMessage]);
681
			}
682
683
			if (bNew)
684
			{
685
				oMessage = this.message();
686
687
				if (oSelectedMessage && oMessage && (
688
					oMessage.folderFullNameRaw !== oSelectedMessage.folderFullNameRaw ||
689
					oMessage.uid !== oSelectedMessage.uid
690
				))
691
				{
692
					this.selectorMessageSelected(null);
693
					if (1 === this.messageList().length)
694
					{
695
						this.selectorMessageFocused(null);
696
					}
697
				}
698
				else if (!oSelectedMessage && oMessage)
699
				{
700
					oSelectedMessage = _.find(this.messageList(), function(oSubMessage) {
701
						return oSubMessage &&
702
							oSubMessage.folderFullNameRaw === oMessage.folderFullNameRaw &&
703
							oSubMessage.uid === oMessage.uid;
704
					});
705
706
					if (oSelectedMessage)
707
					{
708
						this.selectorMessageSelected(oSelectedMessage);
709
						this.selectorMessageFocused(oSelectedMessage);
710
					}
711
				}
712
713
			}
714
715
			Utils.windowResize();
716
		}
717
	}
718
};
719
720
MessageUserStore.prototype.selectMessage = function(oMessage)
721
{
722
	if (oMessage)
723
	{
724
		this.message(this.staticMessage.populateByMessageListItem(oMessage));
725
726
		this.populateMessageBody(this.message());
727
	}
728
	else
729
	{
730
		this.message(null);
731
	}
732
};
733
734
MessageUserStore.prototype.selectMessageByFolderAndUid = function(sFolder, sUid)
735
{
736
	if (sFolder && sUid)
737
	{
738
		this.message(this.staticMessage.populateByMessageListItem(null));
739
		this.message().folderFullNameRaw = sFolder;
740
		this.message().uid = sUid;
741
742
		this.populateMessageBody(this.message());
743
	}
744
	else
745
	{
746
		this.message(null);
747
	}
748
};
749
750
MessageUserStore.prototype.populateMessageBody = function(oMessage)
751
{
752
	if (oMessage)
753
	{
754
		if (Remote.message(this.onMessageResponse, oMessage.folderFullNameRaw, oMessage.uid))
755
		{
756
			this.messageCurrentLoading(true);
757
		}
758
	}
759
};
760
761
/**
762
 * @param {string} sResult
763
 * @param {AjaxJsonDefaultResponse} oData
764
 * @param {boolean} bCached
765
 */
766
MessageUserStore.prototype.onMessageResponse = function(sResult, oData, bCached)
767
{
768
	this.hideMessageBodies();
769
770
	this.messageCurrentLoading(false);
771
772
	if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
773
	{
774
		this.setMessage(oData, bCached);
775
	}
776
	else if (Enums.StorageResultType.Unload === sResult)
777
	{
778
		this.message(null);
779
		this.messageError('');
780
	}
781
	else if (Enums.StorageResultType.Abort !== sResult)
782
	{
783
		this.message(null);
784
		this.messageError((oData && oData.ErrorCode ?
785
			Translator.getNotification(oData.ErrorCode) :
786
			Translator.getNotification(Enums.Notification.UnknownError)));
787
	}
788
};
789
790
/**
791
 * @param {Array} aList
792
 * @returns {string}
793
 */
794
MessageUserStore.prototype.calculateMessageListHash = function(aList)
795
{
796
	return _.map(aList, function(oMessage) {
797
		return '' + oMessage.hash + '_' + oMessage.threadsLen() + '_' + oMessage.flagHash();
798
	}).join('|');
799
};
800
801
MessageUserStore.prototype.setMessageList = function(oData, bCached)
802
{
803
	if (oData && oData.Result && 'Collection/MessageCollection' === oData.Result['@Object'] &&
804
		oData.Result['@Collection'] && Utils.isArray(oData.Result['@Collection']))
805
	{
806
		var
807
			iCount = 0,
808
			iOffset = 0,
809
			aList = [],
810
			iNewCount = 0,
811
			iUtc = require('Common/Momentor').momentNowUnix(),
812
			bUnreadCountChange = false;
813
814
		iCount = Utils.pInt(oData.Result.MessageResultCount);
815
		iOffset = Utils.pInt(oData.Result.Offset);
816
817
		var oFolder = Cache.getFolderFromCacheList(Utils.isNormal(oData.Result.Folder) ? oData.Result.Folder : '');
818
		if (oFolder && !bCached)
819
		{
820
			oFolder.interval = iUtc;
821
822
			Cache.setFolderHash(oData.Result.Folder, oData.Result.FolderHash);
823
824
			if (Utils.isNormal(oData.Result.MessageCount))
825
			{
826
				oFolder.messageCountAll(oData.Result.MessageCount);
827
			}
828
829
			if (Utils.isNormal(oData.Result.MessageUnseenCount))
830
			{
831
				if (Utils.pInt(oFolder.messageCountUnread()) !== Utils.pInt(oData.Result.MessageUnseenCount))
832
				{
833
					bUnreadCountChange = true;
834
				}
835
836
				oFolder.messageCountUnread(oData.Result.MessageUnseenCount);
837
			}
838
839
			this.initUidNextAndNewMessages(oFolder.fullNameRaw, oData.Result.UidNext, oData.Result.NewMessages);
840
		}
841
842
		if (bUnreadCountChange && oFolder)
843
		{
844
			Cache.clearMessageFlagsFromCacheByFolder(oFolder.fullNameRaw);
845
		}
846
847
		_.each(oData.Result['@Collection'], function(oJsonMessage) {
848
			if (oJsonMessage && 'Object/Message' === oJsonMessage['@Object'])
849
			{
850
				var oMessage = MessageModel.newInstanceFromJson(oJsonMessage);
851
				if (oMessage)
852
				{
853
					if (Cache.hasNewMessageAndRemoveFromCache(oMessage.folderFullNameRaw, oMessage.uid) && 5 >= iNewCount)
854
					{
855
						iNewCount += 1;
856
						oMessage.newForAnimation(true);
857
					}
858
859
					oMessage.deleted(false);
860
861
					if (bCached)
862
					{
863
						Cache.initMessageFlagsFromCache(oMessage);
864
					}
865
					else
866
					{
867
						Cache.storeMessageFlagsToCache(oMessage);
868
					}
869
870
					aList.push(oMessage);
871
				}
872
			}
873
		});
874
875
		this.messageListCount(iCount);
876
		this.messageListSearch(Utils.isNormal(oData.Result.Search) ? oData.Result.Search : '');
877
		this.messageListPage(window.Math.ceil((iOffset / SettingsStore.messagesPerPage()) + 1));
878
		this.messageListThreadUid(Utils.isNormal(oData.Result.ThreadUid) ? Utils.pString(oData.Result.ThreadUid) : '');
879
880
		this.messageListEndFolder(Utils.isNormal(oData.Result.Folder) ? oData.Result.Folder : '');
881
		this.messageListEndSearch(this.messageListSearch());
882
		this.messageListEndThreadUid(this.messageListThreadUid());
883
		this.messageListEndPage(this.messageListPage());
884
885
		this.messageListDisableAutoSelect(true);
886
887
		this.messageList(aList);
888
		this.messageListIsNotCompleted(false);
889
890
		Cache.clearNewMessageCache();
891
892
		if (oFolder && (bCached || bUnreadCountChange || SettingsStore.useThreads()))
893
		{
894
			require('App/User').default.folderInformation(oFolder.fullNameRaw, aList);
895
		}
896
	}
897
	else
898
	{
899
		this.messageListCount(0);
900
		this.messageList([]);
901
		this.messageListError(Translator.getNotification(
902
			oData && oData.ErrorCode ? oData.ErrorCode : Enums.Notification.CantGetMessageList
903
		));
904
	}
905
};
906
907
module.exports = new MessageUserStore();
908