mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-30 10:50:08 +00:00 
			
		
		
		
	fixed a couple of minor bugs + added .options.elementShorthand to browse.js + some tweaking...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									55ca190585
								
							
						
					
					
						commit
						5603acbd3b
					
				| @ -594,7 +594,7 @@ var FileSystemLoaderUIActions = actions.Actions({ | |||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				// indicate that we are working...
 | 				// indicate that we are working...
 | ||||||
| 				var spinner = make($('<center><div class="loader"/></center>')) | 				var spinner = make('...') | ||||||
| 
 | 
 | ||||||
| 				// XXX we do not need to actually read anything....
 | 				// XXX we do not need to actually read anything....
 | ||||||
| 				//file.loadIndex(path, that.config['index-dir'], this.logger)
 | 				//file.loadIndex(path, that.config['index-dir'], this.logger)
 | ||||||
| @ -868,7 +868,7 @@ var FileSystemSaveHistoryUIActions = actions.Actions({ | |||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				// indicate that we are working...
 | 				// indicate that we are working...
 | ||||||
| 				var spinner = make($('<center><div class="loader"/></center>')) | 				var spinner = make('...') | ||||||
| 
 | 
 | ||||||
| 				that.loadSaveHistoryList() | 				that.loadSaveHistoryList() | ||||||
| 					.catch(function(err){ | 					.catch(function(err){ | ||||||
|  | |||||||
| @ -564,7 +564,7 @@ module.MetadataFSUI = core.ImageGridFeatures.Feature({ | |||||||
| 					// add a loading indicator...
 | 					// add a loading indicator...
 | ||||||
| 					// NOTE: this will get overwritten when calling .updateMetadata()
 | 					// NOTE: this will get overwritten when calling .updateMetadata()
 | ||||||
| 					data.push('---') | 					data.push('---') | ||||||
| 					data.push($('<center><div class="loader"/></center>')) | 					data.push('...') | ||||||
| 					client.update() | 					client.update() | ||||||
| 
 | 
 | ||||||
| 					reader.then(function(data){ | 					reader.then(function(data){ | ||||||
|  | |||||||
| @ -107,7 +107,7 @@ var SharpActions = actions.Actions({ | |||||||
| 			sizes = (this.config['preview-normalized'] ?  | 			sizes = (this.config['preview-normalized'] ?  | ||||||
| 				sizes | 				sizes | ||||||
| 					.map(function(s){  | 					.map(function(s){  | ||||||
| 						return cfg_sizes.filter(function(c){ return c > s }).pop() || s }) | 						return cfg_sizes.filter(function(c){ return c >= s }).pop() || s }) | ||||||
| 				: sizes) | 				: sizes) | ||||||
| 					.unique() | 					.unique() | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -17,8 +17,7 @@ var core = require('features/core') | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /*********************************************************************/ | /*********************************************************************/ | ||||||
| // helper...
 | //
 | ||||||
| 
 |  | ||||||
| // Change image proportions depending on scale...
 | // Change image proportions depending on scale...
 | ||||||
| //
 | //
 | ||||||
| // A) Small image -- min(screenwidth, screenheight) > threshold
 | // A) Small image -- min(screenwidth, screenheight) > threshold
 | ||||||
| @ -75,125 +74,6 @@ var core = require('features/core') | |||||||
| //
 | //
 | ||||||
| // NOTE: this in part does the same job as .ribbons.correctImageProportionsForRotation(..)
 | // NOTE: this in part does the same job as .ribbons.correctImageProportionsForRotation(..)
 | ||||||
| //
 | //
 | ||||||
| // XXX should this be an action???
 |  | ||||||
| function updateImageProportions(){ |  | ||||||
| 	var that = this |  | ||||||
| 	var threshold = this.config['single-image-proportions-threshold'] |  | ||||||
| 
 |  | ||||||
| 	if(!threshold || threshold == -1){ |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var viewer = this.ribbons.viewer |  | ||||||
| 	var img = this.ribbons.getImage() |  | ||||||
| 
 |  | ||||||
| 	var w = img.outerWidth() |  | ||||||
| 	var h = img.outerHeight() |  | ||||||
| 
 |  | ||||||
| 	// inner diameter
 |  | ||||||
| 	var di = Math.min(h, w) |  | ||||||
| 	// outer diameter -- (m)ax
 |  | ||||||
| 	var dm = Math.max(h, w) |  | ||||||
| 	 |  | ||||||
| 	//var c = Math.min(this.screenwidth, this.screenheight)
 |  | ||||||
| 	var c = this.screenfit  |  | ||||||
| 
 |  | ||||||
| 	// change proportions...
 |  | ||||||
| 	if(c < threshold){ |  | ||||||
| 		var images = viewer.find('.ribbon .image') |  | ||||||
| 
 |  | ||||||
| 		var W = viewer.width() |  | ||||||
| 		var H = viewer.height() |  | ||||||
| 
 |  | ||||||
| 		// inner diameter
 |  | ||||||
| 		var Di = Math.min(W, H) |  | ||||||
| 		// outer diameter -- (m)ax
 |  | ||||||
| 		var Dm = Math.max(W, H) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 		// get dimensional scale....
 |  | ||||||
| 		var s = Di / di  |  | ||||||
| 		// image dimension delta...
 |  | ||||||
| 		var d =  |  | ||||||
| 			// the maximum difference between image and screen proportions...
 |  | ||||||
| 			(Dm / s - di)  |  | ||||||
| 				// coefficient: 0 : c == threshold  ->  1 : c == 1
 |  | ||||||
| 				* (threshold/c - 1) |  | ||||||
| 		// new size...
 |  | ||||||
| 		var n = di + d |  | ||||||
| 
 |  | ||||||
| 		// the amount to compensate ribbon offset for per image...
 |  | ||||||
| 		var x = n - dm |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 		if(n == dm){ |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		getAnimationFrame(function(){ |  | ||||||
| 			that.ribbons.preventTransitions() |  | ||||||
| 
 |  | ||||||
| 			// horizontal viewer...
 |  | ||||||
| 			if(Di == H){ |  | ||||||
| 				var a = 'width' |  | ||||||
| 				var b = 'height' |  | ||||||
| 
 |  | ||||||
| 			// vertical viewer...
 |  | ||||||
| 			} else { |  | ||||||
| 				var a = 'height' |  | ||||||
| 				var b = 'width' |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			images |  | ||||||
| 				.each(function(_, img){ |  | ||||||
| 					var o = img.getAttribute('orientation') |  | ||||||
| 					o = o == null ? 0 : o |  | ||||||
| 
 |  | ||||||
| 					// rotated images...
 |  | ||||||
| 					if(o == 90 || o == 270){ |  | ||||||
| 						img.style[a] = '' |  | ||||||
| 						img.style[b] = n + 'px' |  | ||||||
| 
 |  | ||||||
| 						img.style.margin = -(n - di)/2 +'px '+ (n - di)/2 +'px' |  | ||||||
| 
 |  | ||||||
| 					} else { |  | ||||||
| 						img.style[a] = n + 'px' |  | ||||||
| 						img.style[b] = '' |  | ||||||
| 
 |  | ||||||
| 						img.style.margin = '' |  | ||||||
| 					} |  | ||||||
| 				}) |  | ||||||
| 		 |  | ||||||
| 			that.ribbons |  | ||||||
| 				.centerImage() |  | ||||||
| 				.restoreTransitions(true) |  | ||||||
| 		}) |  | ||||||
| 
 |  | ||||||
| 	// reset proportions to square...
 |  | ||||||
| 	} else if(w != h) { |  | ||||||
| 		var images = viewer.find('.ribbon .image') |  | ||||||
| 
 |  | ||||||
| 		getAnimationFrame(function(){ |  | ||||||
| 			that.ribbons.preventTransitions() |  | ||||||
| 
 |  | ||||||
| 			images |  | ||||||
| 				.each(function(_, img){ |  | ||||||
| 					img.style.width = '' |  | ||||||
| 					img.style.height = '' |  | ||||||
| 
 |  | ||||||
| 					img.style.margin = '' |  | ||||||
| 				}) |  | ||||||
| 
 |  | ||||||
| 			that.ribbons |  | ||||||
| 				.centerImage() |  | ||||||
| 				.restoreTransitions(true) |  | ||||||
| 		}) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //---------------------------------------------------------------------
 |  | ||||||
| 
 | 
 | ||||||
| var SingleImageActions = actions.Actions({ | var SingleImageActions = actions.Actions({ | ||||||
| 	config: { | 	config: { | ||||||
| @ -223,6 +103,123 @@ var SingleImageActions = actions.Actions({ | |||||||
| 		'-single-image-redraw-on-focus': true, | 		'-single-image-redraw-on-focus': true, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
|  | 	updateImageProportions: ['- Interface/', | ||||||
|  | 		function(){ | ||||||
|  | 			var that = this | ||||||
|  | 			var threshold = this.config['single-image-proportions-threshold'] | ||||||
|  | 
 | ||||||
|  | 			if(!threshold || threshold == -1){ | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			var viewer = this.ribbons.viewer | ||||||
|  | 			var img = this.ribbons.getImage() | ||||||
|  | 
 | ||||||
|  | 			var w = img.outerWidth() | ||||||
|  | 			var h = img.outerHeight() | ||||||
|  | 
 | ||||||
|  | 			// inner diameter
 | ||||||
|  | 			var di = Math.min(h, w) | ||||||
|  | 			// outer diameter -- (m)ax
 | ||||||
|  | 			var dm = Math.max(h, w) | ||||||
|  | 			 | ||||||
|  | 			//var c = Math.min(this.screenwidth, this.screenheight)
 | ||||||
|  | 			var c = this.screenfit  | ||||||
|  | 
 | ||||||
|  | 			// change proportions...
 | ||||||
|  | 			if(c < threshold){ | ||||||
|  | 				var images = viewer.find('.ribbon .image') | ||||||
|  | 
 | ||||||
|  | 				var W = viewer.width() | ||||||
|  | 				var H = viewer.height() | ||||||
|  | 
 | ||||||
|  | 				// inner diameter
 | ||||||
|  | 				var Di = Math.min(W, H) | ||||||
|  | 				// outer diameter -- (m)ax
 | ||||||
|  | 				var Dm = Math.max(W, H) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 				// get dimensional scale....
 | ||||||
|  | 				var s = Di / di  | ||||||
|  | 				// image dimension delta...
 | ||||||
|  | 				var d =  | ||||||
|  | 					// the maximum difference between image and screen proportions...
 | ||||||
|  | 					(Dm / s - di)  | ||||||
|  | 						// coefficient: 0 : c == threshold  ->  1 : c == 1
 | ||||||
|  | 						* (threshold/c - 1) | ||||||
|  | 				// new size...
 | ||||||
|  | 				var n = di + d | ||||||
|  | 
 | ||||||
|  | 				// the amount to compensate ribbon offset for per image...
 | ||||||
|  | 				var x = n - dm | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 				if(n == dm){ | ||||||
|  | 					return | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				getAnimationFrame(function(){ | ||||||
|  | 					that.ribbons.preventTransitions() | ||||||
|  | 
 | ||||||
|  | 					// horizontal viewer...
 | ||||||
|  | 					if(Di == H){ | ||||||
|  | 						var a = 'width' | ||||||
|  | 						var b = 'height' | ||||||
|  | 
 | ||||||
|  | 					// vertical viewer...
 | ||||||
|  | 					} else { | ||||||
|  | 						var a = 'height' | ||||||
|  | 						var b = 'width' | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					images | ||||||
|  | 						.each(function(_, img){ | ||||||
|  | 							var o = img.getAttribute('orientation') | ||||||
|  | 							o = o == null ? 0 : o | ||||||
|  | 
 | ||||||
|  | 							// rotated images...
 | ||||||
|  | 							if(o == 90 || o == 270){ | ||||||
|  | 								img.style[a] = '' | ||||||
|  | 								img.style[b] = n + 'px' | ||||||
|  | 
 | ||||||
|  | 								img.style.margin = -(n - di)/2 +'px '+ (n - di)/2 +'px' | ||||||
|  | 
 | ||||||
|  | 							} else { | ||||||
|  | 								img.style[a] = n + 'px' | ||||||
|  | 								img.style[b] = '' | ||||||
|  | 
 | ||||||
|  | 								img.style.margin = '' | ||||||
|  | 							} | ||||||
|  | 						}) | ||||||
|  | 				 | ||||||
|  | 					that.ribbons | ||||||
|  | 						.centerImage() | ||||||
|  | 						.restoreTransitions(true) | ||||||
|  | 				}) | ||||||
|  | 
 | ||||||
|  | 			// reset proportions to square...
 | ||||||
|  | 			} else if(w != h) { | ||||||
|  | 				var images = viewer.find('.ribbon .image') | ||||||
|  | 
 | ||||||
|  | 				getAnimationFrame(function(){ | ||||||
|  | 					that.ribbons.preventTransitions() | ||||||
|  | 
 | ||||||
|  | 					images | ||||||
|  | 						.each(function(_, img){ | ||||||
|  | 							img.style.width = '' | ||||||
|  | 							img.style.height = '' | ||||||
|  | 
 | ||||||
|  | 							img.style.margin = '' | ||||||
|  | 						}) | ||||||
|  | 
 | ||||||
|  | 					that.ribbons | ||||||
|  | 						.centerImage() | ||||||
|  | 						.restoreTransitions(true) | ||||||
|  | 				}) | ||||||
|  | 			} | ||||||
|  | 		}], | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 	toggleSingleImage: ['Interface/Toggle single image view',  | 	toggleSingleImage: ['Interface/Toggle single image view',  | ||||||
| 		toggler.CSSClassToggler( | 		toggler.CSSClassToggler( | ||||||
| 			function(){ return this.ribbons.viewer },  | 			function(){ return this.ribbons.viewer },  | ||||||
| @ -278,7 +275,7 @@ module.SingleImageView = core.ImageGridFeatures.Feature({ | |||||||
| 
 | 
 | ||||||
| 				// singe image mode -- set image proportions...
 | 				// singe image mode -- set image proportions...
 | ||||||
| 				if(this.toggleSingleImage('?') == 'on'){ | 				if(this.toggleSingleImage('?') == 'on'){ | ||||||
| 					updateImageProportions.call(this) | 					this.updateImageProportions() | ||||||
| 
 | 
 | ||||||
| 					this.config['single-image-scale'] =  | 					this.config['single-image-scale'] =  | ||||||
| 						this[this.config['single-image-scale-unit']] | 						this[this.config['single-image-scale-unit']] | ||||||
| @ -292,7 +289,7 @@ module.SingleImageView = core.ImageGridFeatures.Feature({ | |||||||
| 		['resizeRibbon', | 		['resizeRibbon', | ||||||
| 			function(){ | 			function(){ | ||||||
| 				if(this.toggleSingleImage('?') == 'on'){ | 				if(this.toggleSingleImage('?') == 'on'){ | ||||||
| 					updateImageProportions.call(this) | 					this.updateImageProportions() | ||||||
| 				} | 				} | ||||||
| 			}], | 			}], | ||||||
| 		// NOTE: this is not part of the actual action above because we 
 | 		// NOTE: this is not part of the actual action above because we 
 | ||||||
| @ -319,7 +316,7 @@ module.SingleImageView = core.ImageGridFeatures.Feature({ | |||||||
| 									|| this[this.config['single-image-scale-unit']] | 									|| this[this.config['single-image-scale-unit']] | ||||||
| 						} | 						} | ||||||
| 
 | 
 | ||||||
| 						updateImageProportions.call(this) | 						this.updateImageProportions() | ||||||
| 
 | 
 | ||||||
| 					// ribbon mode -- restore original image size...
 | 					// ribbon mode -- restore original image size...
 | ||||||
| 					} else { | 					} else { | ||||||
|  | |||||||
| @ -300,14 +300,32 @@ var BrowserPrototype = { | |||||||
| 			'close', | 			'close', | ||||||
| 		], | 		], | ||||||
| 
 | 
 | ||||||
| 
 | 		// Shorthand elements...
 | ||||||
| 		// Separator element...
 |  | ||||||
| 	 |  | ||||||
| 		// Element text as passed to make(..) to generate a separator
 |  | ||||||
| 		// element rather than a list element...
 |  | ||||||
| 		//
 | 		//
 | ||||||
| 		// NOTE: if null text checking is disabled...
 | 		// Format:
 | ||||||
| 		elementSeparatorText: null, | 		// 	{
 | ||||||
|  | 		// 		<key>: {
 | ||||||
|  | 		// 			class: <element-class-str>,
 | ||||||
|  | 		// 			html: <element-html-str>,
 | ||||||
|  | 		// 		},
 | ||||||
|  | 		// 		...
 | ||||||
|  | 		// 	}
 | ||||||
|  | 		//
 | ||||||
|  | 		// If make(..) gets passed <key> it will construct and element
 | ||||||
|  | 		// via <element-html-str> with an optional <element-class-str>
 | ||||||
|  | 		//
 | ||||||
|  | 		// NOTE: .class is optional...
 | ||||||
|  | 		// NOTE: set this to null to disable shorthands...
 | ||||||
|  | 		elementShorthand: { | ||||||
|  | 			'---': { | ||||||
|  | 				'class': 'separator', | ||||||
|  | 				'html': '<hr>' | ||||||
|  | 			}, | ||||||
|  | 			'...': { | ||||||
|  | 				'class': 'separator', | ||||||
|  | 				'html': '<center><div class="loader"/></center>', | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
| 
 | 
 | ||||||
| 		// Separator class...
 | 		// Separator class...
 | ||||||
| 		//
 | 		//
 | ||||||
| @ -315,11 +333,6 @@ var BrowserPrototype = { | |||||||
| 		// 		be treated as a separator and not as a list element.
 | 		// 		be treated as a separator and not as a list element.
 | ||||||
| 		// NOTE: to disable class checking set this to null
 | 		// NOTE: to disable class checking set this to null
 | ||||||
| 		elementSeparatorClass: 'separator', | 		elementSeparatorClass: 'separator', | ||||||
| 
 |  | ||||||
| 		// Separator HTML code...
 |  | ||||||
| 		//
 |  | ||||||
| 		// NOTE: if this is null, then '<hr>' is used.
 |  | ||||||
| 		elementSeparatorHTML: '<hr>', |  | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	// XXX TEST: this should prevent event propagation...
 | 	// XXX TEST: this should prevent event propagation...
 | ||||||
| @ -873,15 +886,17 @@ var BrowserPrototype = { | |||||||
| 			buttons = buttons | 			buttons = buttons | ||||||
| 				|| (that.options.itemButtons && that.options.itemButtons.slice()) | 				|| (that.options.itemButtons && that.options.itemButtons.slice()) | ||||||
| 
 | 
 | ||||||
| 			// special case separator...
 | 			// special case: shorthand...
 | ||||||
| 			if(p && (p == that.options.elementSeparatorText | 			if(p && (p in (that.options.elementShorthand || {}) | ||||||
| 					|| (p.hasClass  | 					|| (p.hasClass  | ||||||
| 						&& that.options.elementSeparatorClass  | 						&& p in that.options.elementShorthand | ||||||
| 						&& p.hasClass(that.options.elementSeparatorClass)))){ | 						&& that.options.elementShorthand[p].class | ||||||
|  | 						&& p.hasClass(that.options.elementShorthand[p].class)))){ | ||||||
| 				var res = p | 				var res = p | ||||||
|  | 				var shorthand = that.options.elementShorthand[p] | ||||||
| 				if(typeof(res) == typeof('str')){ | 				if(typeof(res) == typeof('str')){ | ||||||
| 					res = $(that.options.elementSeparatorHTML || '<hr>') | 					res = $(shorthand.html) | ||||||
| 						.addClass(that.options.elementSeparatorClass || '') | 						.addClass(shorthand.class || '') | ||||||
| 				} | 				} | ||||||
| 				res.appendTo(l) | 				res.appendTo(l) | ||||||
| 				return res | 				return res | ||||||
| @ -911,7 +926,7 @@ var BrowserPrototype = { | |||||||
| 				// XXX is this the correct way to do this???
 | 				// XXX is this the correct way to do this???
 | ||||||
| 				var txt = p.text() | 				var txt = p.text() | ||||||
| 				// XXX disable search???
 | 				// XXX disable search???
 | ||||||
| 				console.warn('jQuery objects as browse list elements not yet fully supported.') | 				//console.warn('jQuery objects as browse list elements not yet fully supported.')
 | ||||||
| 
 | 
 | ||||||
| 			// str and other stuff...
 | 			// str and other stuff...
 | ||||||
| 			} else { | 			} else { | ||||||
| @ -2224,8 +2239,6 @@ ListerPrototype.options = { | |||||||
| 	skipDisabledItems: false, | 	skipDisabledItems: false, | ||||||
| 	// NOTE: to disable this set it to false or null
 | 	// NOTE: to disable this set it to false or null
 | ||||||
| 	disableItemPattern: '^- ', | 	disableItemPattern: '^- ', | ||||||
| 
 |  | ||||||
| 	elementSeparatorText: '---', |  | ||||||
| } | } | ||||||
| // XXX should we inherit or copy options???
 | // XXX should we inherit or copy options???
 | ||||||
| // 		...inheriting might pose problems with deleting values reverting
 | // 		...inheriting might pose problems with deleting values reverting
 | ||||||
| @ -2287,8 +2300,6 @@ ListPrototype.options = { | |||||||
| 	// NOTE: to disable this set it to false or null
 | 	// NOTE: to disable this set it to false or null
 | ||||||
| 	disableItemPattern: '^- ', | 	disableItemPattern: '^- ', | ||||||
| 
 | 
 | ||||||
| 	elementSeparatorText: '---', |  | ||||||
| 
 |  | ||||||
| 	list: function(path, make){ | 	list: function(path, make){ | ||||||
| 		var that = this | 		var that = this | ||||||
| 		var data = this.options.data | 		var data = this.options.data | ||||||
|  | |||||||
| @ -2238,8 +2238,10 @@ var RibbonsPrototype = { | |||||||
| 
 | 
 | ||||||
| 				} else if((o == 0 || o == 180) && image_p != viewer_p){ | 				} else if((o == 0 || o == 180) && image_p != viewer_p){ | ||||||
| 					image.css({ | 					image.css({ | ||||||
| 						width: h, | 						//width: h,
 | ||||||
| 						height: w, | 						//height: w,
 | ||||||
|  | 						width: '', | ||||||
|  | 						height: '', | ||||||
| 
 | 
 | ||||||
| 						margin: '', | 						margin: '', | ||||||
| 					}) | 					}) | ||||||
| @ -2248,7 +2250,10 @@ var RibbonsPrototype = { | |||||||
| 			// square image...
 | 			// square image...
 | ||||||
| 			} else { | 			} else { | ||||||
| 				image.css({ | 				image.css({ | ||||||
| 					'margin': '', | 					width: '', | ||||||
|  | 					height: '', | ||||||
|  | 
 | ||||||
|  | 					margin: '', | ||||||
| 				}) | 				}) | ||||||
| 			} | 			} | ||||||
| 		}) | 		}) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user