Completed
Push — master ( 2f8415...e6e0b0 )
by Rain
02:22
created

dev/Promises/AbstractAjax.js   A

Size

Lines of Code 212

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
c 3
b 1
f 0
nc 1
dl 0
loc 212
rs 10
noi 0
1
2
import $ from '$';
3
import Promise from 'Promise';
4
5
import {ajax} from 'Common/Links';
6
import {microtime, isUnd, isNormal, pString, pInt, inArray} from 'Common/Utils';
7
import {DEFAULT_AJAX_TIMEOUT, TOKEN_ERROR_LIMIT, AJAX_ERROR_LIMIT} from 'Common/Consts';
8
import {StorageResultType, Notification} from 'Common/Enums';
9
import {data as GlobalsData} from 'Common/Globals';
10
import * as Plugins from 'Common/Plugins';
11
import * as Settings from 'Storage/Settings';
12
13
import {AbstractBasicPromises} from 'Promises/AbstractBasic';
14
15
class AbstractAjaxPromises extends AbstractBasicPromises
16
{
17
	oRequests = {};
18
19
	constructor() {
20
		super();
21
22
		this.clear();
23
	}
24
25
	clear() {
26
		this.oRequests = {};
27
	}
28
29
	abort(sAction, bClearOnly) {
30
		if (this.oRequests[sAction])
31
		{
32
			if (!bClearOnly && this.oRequests[sAction].abort)
33
			{
34
				this.oRequests[sAction].__aborted__ = true;
35
				this.oRequests[sAction].abort();
36
			}
37
38
			this.oRequests[sAction] = null;
39
			delete this.oRequests[sAction];
40
		}
41
42
		return this;
43
	}
44
45
	ajaxRequest(action, isPost, timeOut, params, additionalGetString, fTrigger) {
46
47
		return new Promise((resolve, reject) => {
48
49
			const start = microtime();
50
51
			timeOut = isNormal(timeOut) ? timeOut : DEFAULT_AJAX_TIMEOUT;
52
			additionalGetString = isUnd(additionalGetString) ? '' : pString(additionalGetString);
53
54
			if (isPost)
55
			{
56
				params.XToken = Settings.appSettingsGet('token');
57
			}
58
59
			Plugins.runHook('ajax-default-request', [action, params, additionalGetString]);
60
61
			this.setTrigger(fTrigger, true);
62
63
			const oH = $.ajax({
64
				type: isPost ? 'POST' : 'GET',
65
				url: ajax(additionalGetString),
66
				async: true,
67
				dataType: 'json',
68
				data: isPost ? (params || {}) : {},
69
				timeout: timeOut,
70
				global: true
71
			}).always((data, textStatus) => {
72
73
				let
74
					isCached = false,
75
					errorData = null;
76
77
				if (data && data.Time)
78
				{
79
					isCached = pInt(data.Time) > microtime() - start;
80
				}
81
82
				// backward capability
83
				let type = '';
84
				switch (true)
85
				{
86
					case 'success' === textStatus && data && data.Result && action === data.Action:
87
						type = StorageResultType.Success;
88
						break;
89
					case 'abort' === textStatus && (!data || !data.__aborted__):
90
						type = StorageResultType.Abort;
91
						break;
92
					default:
93
						type = StorageResultType.Error;
94
						break;
95
				}
96
97
				Plugins.runHook('ajax-default-response', [
98
					action, StorageResultType.Success === type ? data : null, type, isCached, params
99
				]);
100
101
				if ('success' === textStatus)
102
				{
103
					if (data && data.Result && action === data.Action)
104
					{
105
						data.__cached__ = isCached;
106
						resolve(data);
107
					}
108
					else if (data && data.Action)
109
					{
110
						errorData = data;
111
						reject(data.ErrorCode ? data.ErrorCode : Notification.AjaxFalse);
112
					}
113
					else
114
					{
115
						errorData = data;
116
						reject(Notification.AjaxParse);
117
					}
118
				}
119
				else if ('timeout' === textStatus)
120
				{
121
					errorData = data;
122
					reject(Notification.AjaxTimeout);
123
				}
124
				else if ('abort' === textStatus)
125
				{
126
					if (!data || !data.__aborted__)
127
					{
128
						reject(Notification.AjaxAbort);
129
					}
130
				}
131
				else
132
				{
133
					errorData = data;
134
					reject(Notification.AjaxParse);
135
				}
136
137
				if (this.oRequests[action])
138
				{
139
					this.oRequests[action] = null;
140
					delete this.oRequests[action];
141
				}
142
143
				this.setTrigger(fTrigger, false);
144
145
				if (errorData)
146
				{
147
					if (-1 < inArray(errorData.ErrorCode, [
148
						Notification.AuthError, Notification.AccessError,
149
						Notification.ConnectionError, Notification.DomainNotAllowed, Notification.AccountNotAllowed,
150
						Notification.MailServerError,	Notification.UnknownNotification, Notification.UnknownError
151
					]))
152
					{
153
						GlobalsData.iAjaxErrorCount += 1;
154
					}
155
156
					if (Notification.InvalidToken === errorData.ErrorCode)
157
					{
158
						GlobalsData.iTokenErrorCount += 1;
159
					}
160
161
					if (TOKEN_ERROR_LIMIT < GlobalsData.iTokenErrorCount)
162
					{
163
						if (GlobalsData.__APP__ && GlobalsData.__APP__.loginAndLogoutReload)
164
						{
165
							GlobalsData.__APP__.loginAndLogoutReload(false, true);
166
						}
167
					}
168
169
					if (errorData.ClearAuth || errorData.Logout || AJAX_ERROR_LIMIT < GlobalsData.iAjaxErrorCount)
170
					{
171
						if (GlobalsData.__APP__ && GlobalsData.__APP__.clearClientSideToken)
172
						{
173
							GlobalsData.__APP__.clearClientSideToken();
174
						}
175
176
						if (GlobalsData.__APP__ && !errorData.ClearAuth && GlobalsData.__APP__.loginAndLogoutReload)
177
						{
178
							GlobalsData.__APP__.loginAndLogoutReload(false, true);
179
						}
180
					}
181
				}
182
183
			});
184
185
			if (oH)
186
			{
187
				if (this.oRequests[action])
188
				{
189
					this.oRequests[action] = null;
190
					delete this.oRequests[action];
191
				}
192
193
				this.oRequests[action] = oH;
194
			}
195
		});
196
	}
197
198
	getRequest(sAction, fTrigger, sAdditionalGetString, iTimeOut) {
199
200
		sAdditionalGetString = isUnd(sAdditionalGetString) ? '' : pString(sAdditionalGetString);
201
		sAdditionalGetString = sAction + '/' + sAdditionalGetString;
202
203
		return this.ajaxRequest(sAction, false, iTimeOut, null, sAdditionalGetString, fTrigger);
204
	}
205
206
	postRequest(action, fTrigger, params, timeOut) {
207
208
		params = params || {};
209
		params.Action = action;
210
211
		return this.ajaxRequest(action, true, timeOut, params, '', fTrigger);
212
	}
213
}
214
215
export {AbstractAjaxPromises, AbstractAjaxPromises as default};
216