Completed
Push — master ( b17e10...8056b4 )
by Maxence
03:04
created

js/circles.app.navigation.js   D

Complexity

Total Complexity 71
Complexity/F 1.97

Size

Lines of Code 389
Function Count 36

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 71
c 4
b 0
f 0
dl 0
loc 389
rs 4.0769
cc 0
nc 1
mnd 3
bc 78
fnc 36
bpm 2.1666
cpm 1.9722
noi 0

18 Functions

Rating   Name   Duplication   Size   Complexity  
B nav.displayMembersInteraction 0 24 6
A nav.displayLinkCircleInput 0 11 2
A nav.initElementsLinkCircleNavigation 0 17 1
A nav.circlesActionReturn 0 8 1
A nav.displayCirclesList 0 21 1
A nav.displayNonMemberInteraction 0 21 3
A nav.displayCircleDetails 0 7 1
B nav.displayMembers 0 80 6
A nav.displayAddMemberInput 0 11 2
A nav.displayInviteCircleButtons 0 10 2
B nav.initElementsCircleNavigation 0 33 1
A nav.initNavigation 0 12 2
B nav.displayJoinCircleButton 0 29 5
A nav.resetCirclesTypeSelection 0 8 1
A nav.displayOptionsNewCircle 0 12 2
A nav.displayCircleButtons 0 11 2
A nav.joinCircleAction 0 6 1
B nav.initElementsAddMemberNavigation 0 31 1

How to fix   Complexity   

Complexity

Complex classes like js/circles.app.navigation.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/*
2
 * Circles - Bring cloud-users closer together.
3
 *
4
 * This file is licensed under the Affero General Public License version 3 or
5
 * later. See the COPYING file.
6
 *
7
 * @author Maxence Lange <[email protected]>
8
 * @copyright 2017
9
 * @license GNU AGPL version 3 or any later version
10
 *
11
 * This program is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License as
13
 * published by the Free Software Foundation, either version 3 of the
14
 * License, or (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU Affero General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License
22
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
 *
24
 */
25
26
/** global: OC */
27
/** global: OCA */
28
/** global: Notyf */
29
30
/** global: actions */
31
/** global: nav */
32
/** global: elements */
33
/** global: settings */
34
/** global: resultCircles */
35
/** global: resultMembers */
36
/** global: resultLinks */
37
/** global: curr */
38
/** global: api */
39
/** global: define */
40
41
var nav = {
42
43
	initNavigation: function () {
44
		this.initElementsAddMemberNavigation();
45
		this.initElementsLinkCircleNavigation();
46
		this.initElementsCircleNavigation();
47
48
		this.displayCirclesList('all');
49
50
		var circleId = window.location.hash.substr(1);
51
		if (circleId) {
52
			actions.selectCircle(circleId);
53
		}
54
	},
55
56
57
	initElementsAddMemberNavigation: function () {
58
59
		elements.addMember.hide();
60
		elements.addMember.on('input propertychange paste focus', function () {
61
			var search = $(this).val().trim();
62
			if (search === '') {
63
				elements.membersSearchResult.fadeOut(400);
64
				return;
65
			}
66
67
			actions.searchMembersRequest(search);
68
			if (elements.membersSearchResult.children().length === 0) {
69
				elements.membersSearchResult.fadeOut(400);
70
			} else {
71
				elements.membersSearchResult.fadeIn(400);
72
			}
73
		}).blur(function () {
74
			elements.membersSearchResult.fadeOut(400);
75
			nav.circlesActionReturn();
76
		});
77
		elements.addMember.on('keydown', function (e) {
78
			if (e.keyCode === 27) {
79
				nav.circlesActionReturn();
80
			}
81
			if (e.keyCode === 13) {
82
				api.addMember(curr.circle, $(this).val(), resultMembers.addMemberResult);
83
			}
84
85
		});
86
87
	},
88
89
90
	initElementsLinkCircleNavigation: function () {
91
92
		elements.linkCircle.hide();
93
		elements.linkCircle.on('keydown', function (e) {
94
95
			if (e.keyCode === 27) {
96
				nav.circlesActionReturn();
97
			}
98
			if (e.keyCode !== 13) {
99
				return;
100
			}
101
102
			api.linkCircle(curr.circle, elements.linkCircle.val(), resultLinks.linkCircleResult);
103
		}).blur(function () {
104
			nav.circlesActionReturn();
105
		});
106
	},
107
108
109
	initElementsCircleNavigation: function () {
110
111
		elements.joinCircle.hide();
112
		elements.joinCircle.on('click', function () {
113
			api.joinCircle(curr.circle, resultCircles.joinCircleResult);
114
			nav.circlesActionReturn();
115
		});
116
117
		elements.leaveCircle.hide();
118
		elements.leaveCircle.on('click', function () {
119
			api.leaveCircle(curr.circle, resultCircles.leaveCircleResult);
120
			nav.circlesActionReturn();
121
		});
122
123
		elements.destroyCircle.on('click', function () {
124
			OC.dialogs.confirm(
125
				t('circles', 'Are you sure you want to delete this circle?'),
126
				t('circles', 'Please confirm'),
127
				function (e) {
128
					if (e === true) {
129
						api.destroyCircle(curr.circle, resultCircles.destroyCircleResult);
130
					}
131
				});
132
		});
133
134
		elements.joinCircleAccept.on('click', function () {
135
			api.joinCircle(curr.circle, resultCircles.joinCircleResult);
136
		});
137
138
		elements.joinCircleReject.on('click', function () {
139
			api.leaveCircle(curr.circle, resultCircles.leaveCircleResult);
140
		});
141
	},
142
143
144
	displayCirclesList: function (type) {
145
146
		curr.circlesType = type;
147
		curr.searchCircle = '';
148
		curr.searchUser = '';
149
150
		curr.circle = 0;
151
		curr.circleLevel = 0;
152
153
		elements.navigation.show('slide', 800);
154
		elements.emptyContent.show(800);
155
		elements.mainUI.fadeOut(800);
156
157
		elements.circlesSearch.val('');
158
		elements.addMember.val('');
159
		elements.linkCircle.val('');
160
161
		this.resetCirclesTypeSelection(type);
162
		elements.resetCirclesList();
163
		api.listCircles(type, '', 0, resultCircles.listCirclesResult);
164
	},
165
166
167
	resetCirclesTypeSelection: function (type) {
168
		elements.circlesList.children('div').removeClass('selected');
169
		elements.circlesList.children().each(function () {
170
			if ($(this).attr('circle-type') === type.toLowerCase()) {
171
				$(this).addClass('selected');
172
			}
173
		});
174
	},
175
176
	circlesActionReturn: function () {
177
		nav.displayCircleButtons(true);
178
		settings.displaySettings(false);
179
		nav.displayAddMemberInput(false);
180
		nav.displayLinkCircleInput(false);
181
		nav.displayJoinCircleButton(false);
182
		nav.displayInviteCircleButtons(false);
183
	},
184
185
	joinCircleAction: function () {
186
		nav.displayCircleButtons(false);
187
		nav.displayAddMemberInput(false);
188
		nav.displayLinkCircleInput(false);
189
		nav.displayJoinCircleButton(true);
190
	},
191
192
	displayCircleButtons: function (display) {
193
		if (display) {
194
			elements.buttonCircleActionReturn.hide(define.animationMenuSpeed);
195
			elements.buttonCircleActions.delay(define.animationMenuSpeed).show(
196
				define.animationMenuSpeed);
197
		} else {
198
			elements.buttonCircleActions.hide(define.animationMenuSpeed);
199
			elements.buttonCircleActionReturn.delay(define.animationMenuSpeed).show(
200
				define.animationMenuSpeed);
201
		}
202
	},
203
204
	displayAddMemberInput: function (display) {
205
		if (display) {
206
			elements.addMember.val('');
207
			elements.addMember.delay(define.animationMenuSpeed).show(define.animationMenuSpeed,
208
				function () {
209
					$(this).focus();
210
				});
211
		} else {
212
			elements.addMember.hide(define.animationMenuSpeed);
213
		}
214
	},
215
216
	displayLinkCircleInput: function (display) {
217
		if (display) {
218
			elements.linkCircle.val('');
219
			elements.linkCircle.delay(define.animationMenuSpeed).show(define.animationMenuSpeed,
220
				function () {
221
					$(this).focus();
222
				});
223
		} else {
224
			elements.linkCircle.hide(define.animationMenuSpeed);
225
		}
226
	},
227
228
229
230
	displayInviteCircleButtons: function (display) {
231
		if (display) {
232
			elements.joinCircleAccept.show(define.animationMenuSpeed);
233
			elements.joinCircleReject.delay(define.animationMenuSpeed).show(
234
				define.animationMenuSpeed);
235
		} else {
236
			elements.joinCircleAccept.hide(define.animationMenuSpeed);
237
			elements.joinCircleReject.hide(define.animationMenuSpeed);
238
		}
239
	},
240
241
	displayJoinCircleButton: function (display) {
242
		if (display) {
243
			if (curr.circleStatus === 'Invited') {
244
				elements.joinCircle.hide(define.animationMenuSpeed);
245
				elements.leaveCircle.hide(define.animationMenuSpeed);
246
				nav.displayInviteCircleButtons(true);
247
248
			} else {
249
				nav.displayInviteCircleButtons(false);
250
251
				if (curr.circleLevel === 0 && curr.circleStatus !== 'Requesting') {
252
					elements.joinCircle.delay(define.animationMenuSpeed).show(
253
						define.animationMenuSpeed);
254
					elements.leaveCircle.hide(define.animationMenuSpeed);
255
					elements.joinCircleAccept.hide(define.animationMenuSpeed);
256
					elements.joinCircleReject.hide(define.animationMenuSpeed);
257
258
				}
259
				else {
260
					elements.leaveCircle.delay(define.animationMenuSpeed).show(
261
						define.animationMenuSpeed);
262
					elements.joinCircle.hide(define.animationMenuSpeed);
263
				}
264
			}
265
		} else {
266
			elements.joinCircle.hide(define.animationMenuSpeed);
267
			elements.leaveCircle.hide(define.animationMenuSpeed);
268
		}
269
	},
270
271
272
	/**
273
	 *
274
	 * @param display
275
	 */
276
	displayOptionsNewCircle: function (display) {
277
		if (display) {
278
			elements.newType.fadeIn(300);
279
			elements.newSubmit.fadeIn(500);
280
			elements.newTypeDefinition.fadeIn(700);
281
		}
282
		else {
283
			elements.newType.fadeOut(700);
284
			elements.newSubmit.fadeOut(500);
285
			elements.newTypeDefinition.fadeOut(300);
286
		}
287
	},
288
289
290
	displayMembers: function (members) {
291
292
		elements.remMember.fadeOut(300);
293
		elements.rightPanel.fadeOut(300);
294
295
		elements.mainUIMembersTable.emptyTable();
296
		if (members === null) {
297
			elements.mainUIMembersTable.hide(200);
298
			return;
299
		}
300
301
		elements.mainUIMembersTable.show(200);
302
		for (var i = 0; i < members.length; i++) {
303
			var tmpl = elements.generateTmplMember(members[i]);
304
			elements.mainUIMembersTable.append(tmpl);
305
		}
306
307
		for (i = 0; i < 10; i++) {
308
			if (curr.circleLevel < 9 && curr.circleLevel <= i) {
309
				$('.level-select option[value="' + i + '"]').attr('disabled', 'disabled');
310
			}
311
		}
312
313
314
		elements.mainUIMembersTable.children('tr.entry').each(function () {
315
316
				var userId = $(this).attr('member-id');
317
318
				//
319
				// level
320
				var level = $(this).attr('member-level');
321
				var levelSelect = $(this).find('.level-select');
322
				if (level === '0') {
323
					levelSelect.hide();
324
				}
325
				else {
326
					levelSelect.show(200).val(level);
327
				}
328
				levelSelect.on('change', function () {
329
					actions.changeMemberLevel(userId, $(this).val());
330
				});
331
332
				//
333
				// status
334
				var status = $(this).attr('member-status');
335
				var statusSelect = $(this).find('.status-select');
336
337
				statusSelect.on('change', function () {
338
					actions.changeMemberStatus(userId, $(this).val());
339
				});
340
				statusSelect.append($('<option>', {
341
					value: status,
342
					text: t('circles', status)
343
				})).val(status);
344
345
				if (curr.circleLevel <= $(this).attr('member-level')) {
346
					return;
347
				}
348
349
				if (status === 'Member' || status === 'Invited') {
350
					statusSelect.append($('<option>', {
351
						value: 'remove_member',
352
						text: t('circles', 'Kick this member')
353
					}));
354
				}
355
356
				if (status === 'Requesting') {
357
					statusSelect.append($('<option>', {
358
						value: 'accept_request',
359
						text: t('circles', 'Accept the request')
360
					}));
361
					statusSelect.append($('<option>', {
362
						value: 'dismiss_request',
363
						text: t('circles', 'Dismiss the request')
364
					}));
365
				}
366
367
			}
368
		);
369
	},
370
371
372
	displayCircleDetails: function (details) {
373
		elements.circlesDetails.children('#name').text(details.name);
374
		elements.circlesDetails.children('#type').text(t('circles', details.typeLongString));
375
376
		elements.buttonCircleActions.show(300);
377
		elements.addMember.hide(300);
378
	},
379
380
381
	displayMembersInteraction: function (details) {
382
		if (details.user.level < define.levelModerator) {
383
			elements.buttonAddMember.hide();
384
		} else {
385
			elements.buttonAddMember.show();
386
		}
387
388
		if (curr.allowed_federated === '0' || details.type === 'Personal' ||
389
			details.user.level < define.levelAdmin) {
390
			elements.buttonLinkCircle.hide();
391
		} else {
392
			elements.buttonLinkCircle.show();
393
		}
394
395
		elements.joinCircleInteraction.hide();
396
		this.displayNonMemberInteraction(details);
397
398
		if (details.user.level === define.levelOwner) {
399
			elements.destroyCircle.show();
400
			elements.buttonCircleSettings.show();
401
			elements.buttonJoinCircle.hide();
402
		}
403
404
	},
405
406
407
	displayNonMemberInteraction: function (details) {
408
		elements.joinCircleAccept.hide();
409
		elements.joinCircleReject.hide();
410
		elements.joinCircleRequest.hide();
411
		elements.joinCircleInvite.hide();
412
		elements.buttonCircleSettings.hide();
413
		elements.destroyCircle.hide();
414
415
		if (details.user.status === 'Requesting') {
416
			elements.joinCircleRequest.show();
417
			return;
418
		}
419
420
		if (details.user.level > 0) {
421
			return;
422
		}
423
424
		setTimeout(function () {
425
			nav.joinCircleAction();
426
		}, 200);
427
	}
428
429
};
430
431