mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 19:15:58 +01:00 
			
		
		
		
	refactor: move picture change client-side logic to its own rjs module
This commit is contained in:
		| @@ -2,11 +2,10 @@ | |||||||
|  |  | ||||||
| define('forum/account/edit', [ | define('forum/account/edit', [ | ||||||
| 	'forum/account/header', | 	'forum/account/header', | ||||||
|  | 	'accounts/picture', | ||||||
| 	'translator', | 	'translator', | ||||||
| 	'pictureCropper', |  | ||||||
| 	'benchpress', |  | ||||||
| 	'api', | 	'api', | ||||||
| ], function (header, translator, pictureCropper, Benchpress, api) { | ], function (header, picture, translator, api) { | ||||||
| 	var AccountEdit = {}; | 	var AccountEdit = {}; | ||||||
|  |  | ||||||
| 	AccountEdit.init = function () { | 	AccountEdit.init = function () { | ||||||
| @@ -56,126 +55,15 @@ define('forum/account/edit', [ | |||||||
| 				$('#user-current-picture').attr('src', res.picture); | 				$('#user-current-picture').attr('src', res.picture); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			updateHeader(res.picture); | 			picture.updateHeader(res.picture); | ||||||
| 		}).catch(app.alertError); | 		}).catch(app.alertError); | ||||||
|  |  | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	function updateHeader(picture, iconBgColor) { |  | ||||||
| 		if (parseInt(ajaxify.data.theirid, 10) !== parseInt(ajaxify.data.yourid, 10)) { |  | ||||||
| 			return; |  | ||||||
| 		} |  | ||||||
| 		if (!picture && ajaxify.data.defaultAvatar) { |  | ||||||
| 			picture = ajaxify.data.defaultAvatar; |  | ||||||
| 		} |  | ||||||
| 		$('#header [component="avatar/picture"]')[picture ? 'show' : 'hide'](); |  | ||||||
| 		$('#header [component="avatar/icon"]')[!picture ? 'show' : 'hide'](); |  | ||||||
| 		if (picture) { |  | ||||||
| 			$('#header [component="avatar/picture"]').attr('src', picture); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if (iconBgColor) { |  | ||||||
| 			document.querySelectorAll('[component="navbar"] [component="avatar/icon"]').forEach((el) => { |  | ||||||
| 				el.style['background-color'] = iconBgColor; |  | ||||||
| 			}); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	function handleImageChange() { | 	function handleImageChange() { | ||||||
| 		$('#changePictureBtn').on('click', function () { | 		$('#changePictureBtn').on('click', function () { | ||||||
| 			socket.emit('user.getProfilePictures', { | 			picture.openChangeModal(); | ||||||
| 				uid: ajaxify.data.uid, |  | ||||||
| 			}, function (err, pictures) { |  | ||||||
| 				if (err) { |  | ||||||
| 					return app.alertError(err.message); |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				// boolean to signify whether an uploaded picture is present in the pictures list |  | ||||||
| 				var uploaded = pictures.reduce(function (memo, cur) { |  | ||||||
| 					return memo || cur.type === 'uploaded'; |  | ||||||
| 				}, false); |  | ||||||
|  |  | ||||||
| 				app.parseAndTranslate('partials/modals/change_picture_modal', { |  | ||||||
| 					pictures: pictures, |  | ||||||
| 					uploaded: uploaded, |  | ||||||
| 					icon: { text: ajaxify.data['icon:text'], bgColor: ajaxify.data['icon:bgColor'] }, |  | ||||||
| 					defaultAvatar: ajaxify.data.defaultAvatar, |  | ||||||
| 					allowProfileImageUploads: ajaxify.data.allowProfileImageUploads, |  | ||||||
| 					iconBackgrounds: config.iconBackgrounds, |  | ||||||
| 				}, function (html) { |  | ||||||
| 					var modal = bootbox.dialog({ |  | ||||||
| 						className: 'picture-switcher', |  | ||||||
| 						title: '[[user:change_picture]]', |  | ||||||
| 						message: html, |  | ||||||
| 						show: true, |  | ||||||
| 						buttons: { |  | ||||||
| 							close: { |  | ||||||
| 								label: '[[global:close]]', |  | ||||||
| 								callback: onCloseModal, |  | ||||||
| 								className: 'btn-link', |  | ||||||
| 							}, |  | ||||||
| 							update: { |  | ||||||
| 								label: '[[global:save_changes]]', |  | ||||||
| 								callback: saveSelection, |  | ||||||
| 							}, |  | ||||||
| 						}, |  | ||||||
| 					}); |  | ||||||
|  |  | ||||||
| 					modal.on('shown.bs.modal', updateImages); |  | ||||||
| 					modal.on('click', '.list-group-item', function selectImageType() { |  | ||||||
| 						modal.find('.list-group-item').removeClass('active'); |  | ||||||
| 						$(this).addClass('active'); |  | ||||||
| 					}); |  | ||||||
| 					modal.on('change', 'input[type="radio"][name="icon:bgColor"]', (e) => { |  | ||||||
| 						const value = e.target.value; |  | ||||||
| 						modal.find('.user-icon').css('background-color', value); |  | ||||||
| 					}); |  | ||||||
|  |  | ||||||
| 					handleImageUpload(modal); |  | ||||||
|  |  | ||||||
| 					function updateImages() { |  | ||||||
| 						// Check to see which one is the active picture |  | ||||||
| 						if (!ajaxify.data.picture) { |  | ||||||
| 							modal.find('.list-group-item .user-icon').parents('.list-group-item').addClass('active'); |  | ||||||
| 						} else { |  | ||||||
| 							modal.find('.list-group-item img').each(function () { |  | ||||||
| 								if (this.getAttribute('src') === ajaxify.data.picture) { |  | ||||||
| 									$(this).parents('.list-group-item').addClass('active'); |  | ||||||
| 								} |  | ||||||
| 							}); |  | ||||||
| 						} |  | ||||||
|  |  | ||||||
| 						// Update avatar background colour |  | ||||||
| 						const radioEl = document.querySelector(`.modal input[type="radio"][value="${ajaxify.data['icon:bgColor']}"]`); |  | ||||||
| 						if (radioEl) { |  | ||||||
| 							radioEl.checked = true; |  | ||||||
| 						} else { |  | ||||||
| 							// Check the first one |  | ||||||
| 							document.querySelector('.modal input[type="radio"]').checked = true; |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
|  |  | ||||||
| 					function saveSelection() { |  | ||||||
| 						var type = modal.find('.list-group-item.active').attr('data-type'); |  | ||||||
| 						const iconBgColor = document.querySelector('.modal.picture-switcher input[type="radio"]:checked').value || 'transparent'; |  | ||||||
|  |  | ||||||
| 						changeUserPicture(type, iconBgColor, function (err) { |  | ||||||
| 							if (err) { |  | ||||||
| 								return app.alertError(err.message); |  | ||||||
| 							} |  | ||||||
|  |  | ||||||
| 							updateHeader(type === 'default' ? '' : modal.find('.list-group-item.active img').attr('src'), iconBgColor); |  | ||||||
| 							ajaxify.refresh(); |  | ||||||
| 						}); |  | ||||||
| 					} |  | ||||||
|  |  | ||||||
| 					function onCloseModal() { |  | ||||||
| 						modal.modal('hide'); |  | ||||||
| 					} |  | ||||||
| 				}); |  | ||||||
| 			}); |  | ||||||
|  |  | ||||||
| 			return false; | 			return false; | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| @@ -222,92 +110,6 @@ define('forum/account/edit', [ | |||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	function handleImageUpload(modal) { |  | ||||||
| 		function onUploadComplete(urlOnServer) { |  | ||||||
| 			urlOnServer = (!urlOnServer.startsWith('http') ? config.relative_path : '') + urlOnServer + '?' + Date.now(); |  | ||||||
|  |  | ||||||
| 			updateHeader(urlOnServer); |  | ||||||
|  |  | ||||||
| 			if (ajaxify.data.picture && ajaxify.data.picture.length) { |  | ||||||
| 				$('#user-current-picture, img.avatar').attr('src', urlOnServer); |  | ||||||
| 				ajaxify.data.uploadedpicture = urlOnServer; |  | ||||||
| 			} else { |  | ||||||
| 				ajaxify.refresh(function () { |  | ||||||
| 					$('#user-current-picture, img.avatar').attr('src', urlOnServer); |  | ||||||
| 				}); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		function onRemoveComplete() { |  | ||||||
| 			if (ajaxify.data.uploadedpicture === ajaxify.data.picture) { |  | ||||||
| 				ajaxify.refresh(); |  | ||||||
| 				updateHeader(); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		modal.find('[data-action="upload"]').on('click', function () { |  | ||||||
| 			modal.modal('hide'); |  | ||||||
|  |  | ||||||
| 			pictureCropper.show({ |  | ||||||
| 				socketMethod: 'user.uploadCroppedPicture', |  | ||||||
| 				route: config.relative_path + '/api/user/' + ajaxify.data.userslug + '/uploadpicture', |  | ||||||
| 				aspectRatio: 1 / 1, |  | ||||||
| 				paramName: 'uid', |  | ||||||
| 				paramValue: ajaxify.data.theirid, |  | ||||||
| 				fileSize: ajaxify.data.maximumProfileImageSize, |  | ||||||
| 				allowSkippingCrop: false, |  | ||||||
| 				title: '[[user:upload_picture]]', |  | ||||||
| 				description: '[[user:upload_a_picture]]', |  | ||||||
| 				accept: ajaxify.data.allowedProfileImageExtensions, |  | ||||||
| 			}, function (url) { |  | ||||||
| 				onUploadComplete(url); |  | ||||||
| 			}); |  | ||||||
|  |  | ||||||
| 			return false; |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		modal.find('[data-action="upload-url"]').on('click', function () { |  | ||||||
| 			modal.modal('hide'); |  | ||||||
| 			app.parseAndTranslate('partials/modals/upload_picture_from_url_modal', {}, function (uploadModal) { |  | ||||||
| 				uploadModal.modal('show'); |  | ||||||
|  |  | ||||||
| 				uploadModal.find('.upload-btn').on('click', function () { |  | ||||||
| 					var url = uploadModal.find('#uploadFromUrl').val(); |  | ||||||
| 					if (!url) { |  | ||||||
| 						return false; |  | ||||||
| 					} |  | ||||||
|  |  | ||||||
| 					uploadModal.modal('hide'); |  | ||||||
|  |  | ||||||
| 					pictureCropper.handleImageCrop({ |  | ||||||
| 						url: url, |  | ||||||
| 						socketMethod: 'user.uploadCroppedPicture', |  | ||||||
| 						aspectRatio: 1, |  | ||||||
| 						allowSkippingCrop: false, |  | ||||||
| 						paramName: 'uid', |  | ||||||
| 						paramValue: ajaxify.data.theirid, |  | ||||||
| 					}, onUploadComplete); |  | ||||||
|  |  | ||||||
| 					return false; |  | ||||||
| 				}); |  | ||||||
| 			}); |  | ||||||
|  |  | ||||||
| 			return false; |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		modal.find('[data-action="remove-uploaded"]').on('click', function () { |  | ||||||
| 			socket.emit('user.removeUploadedPicture', { |  | ||||||
| 				uid: ajaxify.data.theirid, |  | ||||||
| 			}, function (err) { |  | ||||||
| 				modal.modal('hide'); |  | ||||||
| 				if (err) { |  | ||||||
| 					return app.alertError(err.message); |  | ||||||
| 				} |  | ||||||
| 				onRemoveComplete(); |  | ||||||
| 			}); |  | ||||||
| 		}); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	function handleEmailConfirm() { | 	function handleEmailConfirm() { | ||||||
| 		$('#confirm-email').on('click', function () { | 		$('#confirm-email').on('click', function () { | ||||||
| 			var btn = $(this).attr('disabled', true); | 			var btn = $(this).attr('disabled', true); | ||||||
| @@ -321,14 +123,6 @@ define('forum/account/edit', [ | |||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	function changeUserPicture(type, bgColor, callback) { |  | ||||||
| 		socket.emit('user.changePicture', { |  | ||||||
| 			type, |  | ||||||
| 			bgColor, |  | ||||||
| 			uid: ajaxify.data.theirid, |  | ||||||
| 		}, callback); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	function getCharsLeft(el, max) { | 	function getCharsLeft(el, max) { | ||||||
| 		return el.length ? '(' + el.val().length + '/' + max + ')' : ''; | 		return el.length ? '(' + el.val().length + '/' + max + ')' : ''; | ||||||
| 	} | 	} | ||||||
|   | |||||||
							
								
								
									
										217
									
								
								public/src/modules/accounts/picture.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								public/src/modules/accounts/picture.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,217 @@ | |||||||
|  | 'use strict'; | ||||||
|  |  | ||||||
|  | define('accounts/picture', [ | ||||||
|  | 	'pictureCropper', | ||||||
|  | ], (pictureCropper) => { | ||||||
|  | 	const Picture = {}; | ||||||
|  |  | ||||||
|  | 	Picture.openChangeModal = () => { | ||||||
|  | 		socket.emit('user.getProfilePictures', { | ||||||
|  | 			uid: ajaxify.data.uid, | ||||||
|  | 		}, function (err, pictures) { | ||||||
|  | 			if (err) { | ||||||
|  | 				return app.alertError(err.message); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			// boolean to signify whether an uploaded picture is present in the pictures list | ||||||
|  | 			var uploaded = pictures.reduce(function (memo, cur) { | ||||||
|  | 				return memo || cur.type === 'uploaded'; | ||||||
|  | 			}, false); | ||||||
|  |  | ||||||
|  | 			app.parseAndTranslate('partials/modals/change_picture_modal', { | ||||||
|  | 				pictures: pictures, | ||||||
|  | 				uploaded: uploaded, | ||||||
|  | 				icon: { text: ajaxify.data['icon:text'], bgColor: ajaxify.data['icon:bgColor'] }, | ||||||
|  | 				defaultAvatar: ajaxify.data.defaultAvatar, | ||||||
|  | 				allowProfileImageUploads: ajaxify.data.allowProfileImageUploads, | ||||||
|  | 				iconBackgrounds: config.iconBackgrounds, | ||||||
|  | 			}, function (html) { | ||||||
|  | 				var modal = bootbox.dialog({ | ||||||
|  | 					className: 'picture-switcher', | ||||||
|  | 					title: '[[user:change_picture]]', | ||||||
|  | 					message: html, | ||||||
|  | 					show: true, | ||||||
|  | 					buttons: { | ||||||
|  | 						close: { | ||||||
|  | 							label: '[[global:close]]', | ||||||
|  | 							callback: onCloseModal, | ||||||
|  | 							className: 'btn-link', | ||||||
|  | 						}, | ||||||
|  | 						update: { | ||||||
|  | 							label: '[[global:save_changes]]', | ||||||
|  | 							callback: saveSelection, | ||||||
|  | 						}, | ||||||
|  | 					}, | ||||||
|  | 				}); | ||||||
|  |  | ||||||
|  | 				modal.on('shown.bs.modal', updateImages); | ||||||
|  | 				modal.on('click', '.list-group-item', function selectImageType() { | ||||||
|  | 					modal.find('.list-group-item').removeClass('active'); | ||||||
|  | 					$(this).addClass('active'); | ||||||
|  | 				}); | ||||||
|  | 				modal.on('change', 'input[type="radio"][name="icon:bgColor"]', (e) => { | ||||||
|  | 					const value = e.target.value; | ||||||
|  | 					modal.find('.user-icon').css('background-color', value); | ||||||
|  | 				}); | ||||||
|  |  | ||||||
|  | 				handleImageUpload(modal); | ||||||
|  |  | ||||||
|  | 				function updateImages() { | ||||||
|  | 					// Check to see which one is the active picture | ||||||
|  | 					if (!ajaxify.data.picture) { | ||||||
|  | 						modal.find('.list-group-item .user-icon').parents('.list-group-item').addClass('active'); | ||||||
|  | 					} else { | ||||||
|  | 						modal.find('.list-group-item img').each(function () { | ||||||
|  | 							if (this.getAttribute('src') === ajaxify.data.picture) { | ||||||
|  | 								$(this).parents('.list-group-item').addClass('active'); | ||||||
|  | 							} | ||||||
|  | 						}); | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					// Update avatar background colour | ||||||
|  | 					const radioEl = document.querySelector(`.modal input[type="radio"][value="${ajaxify.data['icon:bgColor']}"]`); | ||||||
|  | 					if (radioEl) { | ||||||
|  | 						radioEl.checked = true; | ||||||
|  | 					} else { | ||||||
|  | 						// Check the first one | ||||||
|  | 						document.querySelector('.modal input[type="radio"]').checked = true; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				function saveSelection() { | ||||||
|  | 					var type = modal.find('.list-group-item.active').attr('data-type'); | ||||||
|  | 					const iconBgColor = document.querySelector('.modal.picture-switcher input[type="radio"]:checked').value || 'transparent'; | ||||||
|  |  | ||||||
|  | 					changeUserPicture(type, iconBgColor, function (err) { | ||||||
|  | 						if (err) { | ||||||
|  | 							return app.alertError(err.message); | ||||||
|  | 						} | ||||||
|  |  | ||||||
|  | 						Picture.updateHeader(type === 'default' ? '' : modal.find('.list-group-item.active img').attr('src'), iconBgColor); | ||||||
|  | 						ajaxify.refresh(); | ||||||
|  | 					}); | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				function onCloseModal() { | ||||||
|  | 					modal.modal('hide'); | ||||||
|  | 				} | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	Picture.updateHeader = (picture, iconBgColor) => { | ||||||
|  | 		if (parseInt(ajaxify.data.theirid, 10) !== parseInt(ajaxify.data.yourid, 10)) { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 		if (!picture && ajaxify.data.defaultAvatar) { | ||||||
|  | 			picture = ajaxify.data.defaultAvatar; | ||||||
|  | 		} | ||||||
|  | 		$('#header [component="avatar/picture"]')[picture ? 'show' : 'hide'](); | ||||||
|  | 		$('#header [component="avatar/icon"]')[!picture ? 'show' : 'hide'](); | ||||||
|  | 		if (picture) { | ||||||
|  | 			$('#header [component="avatar/picture"]').attr('src', picture); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (iconBgColor) { | ||||||
|  | 			document.querySelectorAll('[component="navbar"] [component="avatar/icon"]').forEach((el) => { | ||||||
|  | 				el.style['background-color'] = iconBgColor; | ||||||
|  | 			}); | ||||||
|  | 		} | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	function handleImageUpload(modal) { | ||||||
|  | 		function onUploadComplete(urlOnServer) { | ||||||
|  | 			urlOnServer = (!urlOnServer.startsWith('http') ? config.relative_path : '') + urlOnServer + '?' + Date.now(); | ||||||
|  |  | ||||||
|  | 			Picture.updateHeader(urlOnServer); | ||||||
|  |  | ||||||
|  | 			if (ajaxify.data.picture && ajaxify.data.picture.length) { | ||||||
|  | 				$('#user-current-picture, img.avatar').attr('src', urlOnServer); | ||||||
|  | 				ajaxify.data.uploadedpicture = urlOnServer; | ||||||
|  | 			} else { | ||||||
|  | 				ajaxify.refresh(function () { | ||||||
|  | 					$('#user-current-picture, img.avatar').attr('src', urlOnServer); | ||||||
|  | 				}); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		function onRemoveComplete() { | ||||||
|  | 			if (ajaxify.data.uploadedpicture === ajaxify.data.picture) { | ||||||
|  | 				ajaxify.refresh(); | ||||||
|  | 				Picture.updateHeader(); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		modal.find('[data-action="upload"]').on('click', function () { | ||||||
|  | 			modal.modal('hide'); | ||||||
|  |  | ||||||
|  | 			pictureCropper.show({ | ||||||
|  | 				socketMethod: 'user.uploadCroppedPicture', | ||||||
|  | 				route: config.relative_path + '/api/user/' + ajaxify.data.userslug + '/uploadpicture', | ||||||
|  | 				aspectRatio: 1 / 1, | ||||||
|  | 				paramName: 'uid', | ||||||
|  | 				paramValue: ajaxify.data.theirid, | ||||||
|  | 				fileSize: ajaxify.data.maximumProfileImageSize, | ||||||
|  | 				allowSkippingCrop: false, | ||||||
|  | 				title: '[[user:upload_picture]]', | ||||||
|  | 				description: '[[user:upload_a_picture]]', | ||||||
|  | 				accept: ajaxify.data.allowedProfileImageExtensions, | ||||||
|  | 			}, function (url) { | ||||||
|  | 				onUploadComplete(url); | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 			return false; | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 		modal.find('[data-action="upload-url"]').on('click', function () { | ||||||
|  | 			modal.modal('hide'); | ||||||
|  | 			app.parseAndTranslate('partials/modals/upload_picture_from_url_modal', {}, function (uploadModal) { | ||||||
|  | 				uploadModal.modal('show'); | ||||||
|  |  | ||||||
|  | 				uploadModal.find('.upload-btn').on('click', function () { | ||||||
|  | 					var url = uploadModal.find('#uploadFromUrl').val(); | ||||||
|  | 					if (!url) { | ||||||
|  | 						return false; | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					uploadModal.modal('hide'); | ||||||
|  |  | ||||||
|  | 					pictureCropper.handleImageCrop({ | ||||||
|  | 						url: url, | ||||||
|  | 						socketMethod: 'user.uploadCroppedPicture', | ||||||
|  | 						aspectRatio: 1, | ||||||
|  | 						allowSkippingCrop: false, | ||||||
|  | 						paramName: 'uid', | ||||||
|  | 						paramValue: ajaxify.data.theirid, | ||||||
|  | 					}, onUploadComplete); | ||||||
|  |  | ||||||
|  | 					return false; | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 			return false; | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 		modal.find('[data-action="remove-uploaded"]').on('click', function () { | ||||||
|  | 			socket.emit('user.removeUploadedPicture', { | ||||||
|  | 				uid: ajaxify.data.theirid, | ||||||
|  | 			}, function (err) { | ||||||
|  | 				modal.modal('hide'); | ||||||
|  | 				if (err) { | ||||||
|  | 					return app.alertError(err.message); | ||||||
|  | 				} | ||||||
|  | 				onRemoveComplete(); | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	function changeUserPicture(type, bgColor, callback) { | ||||||
|  | 		socket.emit('user.changePicture', { | ||||||
|  | 			type, | ||||||
|  | 			bgColor, | ||||||
|  | 			uid: ajaxify.data.theirid, | ||||||
|  | 		}, callback); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return Picture; | ||||||
|  | }); | ||||||
		Reference in New Issue
	
	Block a user