239 Auto-expand message area when typing
This commit is contained in:
		
					parent
					
						
							
								1696898112
							
						
					
				
			
			
				commit
				
					
						07ac0ae9cc
					
				
			
		
					 9 changed files with 522 additions and 54 deletions
				
			
		|  | @ -45,7 +45,7 @@ | |||
|                   <input type='file' class='file-input'> | ||||
|               </div> | ||||
|               <input class="send-btn" type='submit' value='' /> | ||||
|               <input class='send-message' type='textarea' placeholder="Send a message"> | ||||
|               <textarea class='send-message' placeholder="Send a message" rows="1"></textarea> | ||||
|           </form> | ||||
|       </div> | ||||
|   </script> | ||||
|  |  | |||
|  | @ -22,7 +22,8 @@ | |||
|     "blueimp-load-image": "~1.13.0", | ||||
|     "blueimp-canvas-to-blob": "~2.1.1", | ||||
|     "twemoji": "~1.2.1", | ||||
|     "emojijs": "iamcal/js-emoji" | ||||
|     "emojijs": "iamcal/js-emoji", | ||||
|     "autosize": "~3.0.6" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "mocha": "~2.0.1", | ||||
|  | @ -111,6 +112,9 @@ | |||
|     ], | ||||
|     "mock-socket": [ | ||||
|       "dist/mock-socket.js" | ||||
|     ], | ||||
|     "autosize": [ | ||||
|       "dist/autosize.js" | ||||
|     ] | ||||
|   }, | ||||
|   "concat": { | ||||
|  | @ -131,7 +135,8 @@ | |||
|       "blueimp-load-image", | ||||
|       "blueimp-canvas-to-blob", | ||||
|       "twemoji", | ||||
|       "emojijs" | ||||
|       "emojijs", | ||||
|       "autosize" | ||||
|     ], | ||||
|     "libtextsecure": [ | ||||
|       "jquery", | ||||
|  |  | |||
							
								
								
									
										211
									
								
								components/autosize/dist/autosize.js
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								components/autosize/dist/autosize.js
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,211 @@ | |||
| /*! | ||||
| 	Autosize 3.0.5 | ||||
| 	license: MIT | ||||
| 	http://www.jacklmoore.com/autosize
 | ||||
| */ | ||||
| (function (global, factory) { | ||||
| 	if (typeof define === 'function' && define.amd) { | ||||
| 		define(['exports', 'module'], factory); | ||||
| 	} else if (typeof exports !== 'undefined' && typeof module !== 'undefined') { | ||||
| 		factory(exports, module); | ||||
| 	} else { | ||||
| 		var mod = { | ||||
| 			exports: {} | ||||
| 		}; | ||||
| 		factory(mod.exports, mod); | ||||
| 		global.autosize = mod.exports; | ||||
| 	} | ||||
| })(this, function (exports, module) { | ||||
| 	'use strict'; | ||||
| 
 | ||||
| 	function assign(ta) { | ||||
| 		var _ref = arguments[1] === undefined ? {} : arguments[1]; | ||||
| 
 | ||||
| 		var _ref$setOverflowX = _ref.setOverflowX; | ||||
| 		var setOverflowX = _ref$setOverflowX === undefined ? true : _ref$setOverflowX; | ||||
| 		var _ref$setOverflowY = _ref.setOverflowY; | ||||
| 		var setOverflowY = _ref$setOverflowY === undefined ? true : _ref$setOverflowY; | ||||
| 
 | ||||
| 		if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || ta.hasAttribute('data-autosize-on')) return; | ||||
| 
 | ||||
| 		var heightOffset = null; | ||||
| 		var overflowY = 'hidden'; | ||||
| 
 | ||||
| 		function init() { | ||||
| 			var style = window.getComputedStyle(ta, null); | ||||
| 
 | ||||
| 			if (style.resize === 'vertical') { | ||||
| 				ta.style.resize = 'none'; | ||||
| 			} else if (style.resize === 'both') { | ||||
| 				ta.style.resize = 'horizontal'; | ||||
| 			} | ||||
| 
 | ||||
| 			if (style.boxSizing === 'content-box') { | ||||
| 				heightOffset = -(parseFloat(style.paddingTop) + parseFloat(style.paddingBottom)); | ||||
| 			} else { | ||||
| 				heightOffset = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth); | ||||
| 			} | ||||
| 
 | ||||
| 			update(); | ||||
| 		} | ||||
| 
 | ||||
| 		function changeOverflow(value) { | ||||
| 			{ | ||||
| 				// Chrome/Safari-specific fix:
 | ||||
| 				// When the textarea y-overflow is hidden, Chrome/Safari do not reflow the text to account for the space
 | ||||
| 				// made available by removing the scrollbar. The following forces the necessary text reflow.
 | ||||
| 				var width = ta.style.width; | ||||
| 				ta.style.width = '0px'; | ||||
| 				// Force reflow:
 | ||||
| 				/* jshint ignore:start */ | ||||
| 				ta.offsetWidth; | ||||
| 				/* jshint ignore:end */ | ||||
| 				ta.style.width = width; | ||||
| 			} | ||||
| 
 | ||||
| 			overflowY = value; | ||||
| 
 | ||||
| 			if (setOverflowY) { | ||||
| 				ta.style.overflowY = value; | ||||
| 			} | ||||
| 
 | ||||
| 			update(); | ||||
| 		} | ||||
| 
 | ||||
| 		function update() { | ||||
| 			var startHeight = ta.style.height; | ||||
| 			var htmlTop = document.documentElement.scrollTop; | ||||
| 			var bodyTop = document.body.scrollTop; | ||||
| 			var originalHeight = ta.style.height; | ||||
| 
 | ||||
| 			ta.style.height = 'auto'; | ||||
| 
 | ||||
| 			var endHeight = ta.scrollHeight + heightOffset; | ||||
| 
 | ||||
| 			if (ta.scrollHeight === 0) { | ||||
| 				// If the scrollHeight is 0, then the element probably has display:none or is detached from the DOM.
 | ||||
| 				ta.style.height = originalHeight; | ||||
| 				return; | ||||
| 			} | ||||
| 
 | ||||
| 			ta.style.height = endHeight + 'px'; | ||||
| 
 | ||||
| 			// prevents scroll-position jumping
 | ||||
| 			document.documentElement.scrollTop = htmlTop; | ||||
| 			document.body.scrollTop = bodyTop; | ||||
| 
 | ||||
| 			var style = window.getComputedStyle(ta, null); | ||||
| 
 | ||||
| 			if (style.height !== ta.style.height) { | ||||
| 				if (overflowY !== 'visible') { | ||||
| 					changeOverflow('visible'); | ||||
| 					return; | ||||
| 				} | ||||
| 			} else { | ||||
| 				if (overflowY !== 'hidden') { | ||||
| 					changeOverflow('hidden'); | ||||
| 					return; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			if (startHeight !== ta.style.height) { | ||||
| 				var evt = document.createEvent('Event'); | ||||
| 				evt.initEvent('autosize:resized', true, false); | ||||
| 				ta.dispatchEvent(evt); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		var destroy = (function (style) { | ||||
| 			window.removeEventListener('resize', update); | ||||
| 			ta.removeEventListener('input', update); | ||||
| 			ta.removeEventListener('keyup', update); | ||||
| 			ta.removeAttribute('data-autosize-on'); | ||||
| 			ta.removeEventListener('autosize:destroy', destroy); | ||||
| 
 | ||||
| 			Object.keys(style).forEach(function (key) { | ||||
| 				ta.style[key] = style[key]; | ||||
| 			}); | ||||
| 		}).bind(ta, { | ||||
| 			height: ta.style.height, | ||||
| 			resize: ta.style.resize, | ||||
| 			overflowY: ta.style.overflowY, | ||||
| 			overflowX: ta.style.overflowX, | ||||
| 			wordWrap: ta.style.wordWrap }); | ||||
| 
 | ||||
| 		ta.addEventListener('autosize:destroy', destroy); | ||||
| 
 | ||||
| 		// IE9 does not fire onpropertychange or oninput for deletions,
 | ||||
| 		// so binding to onkeyup to catch most of those events.
 | ||||
| 		// There is no way that I know of to detect something like 'cut' in IE9.
 | ||||
| 		if ('onpropertychange' in ta && 'oninput' in ta) { | ||||
| 			ta.addEventListener('keyup', update); | ||||
| 		} | ||||
| 
 | ||||
| 		window.addEventListener('resize', update); | ||||
| 		ta.addEventListener('input', update); | ||||
| 		ta.addEventListener('autosize:update', update); | ||||
| 		ta.setAttribute('data-autosize-on', true); | ||||
| 
 | ||||
| 		if (setOverflowY) { | ||||
| 			ta.style.overflowY = 'hidden'; | ||||
| 		} | ||||
| 		if (setOverflowX) { | ||||
| 			ta.style.overflowX = 'hidden'; | ||||
| 			ta.style.wordWrap = 'break-word'; | ||||
| 		} | ||||
| 
 | ||||
| 		init(); | ||||
| 	} | ||||
| 
 | ||||
| 	function destroy(ta) { | ||||
| 		if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return; | ||||
| 		var evt = document.createEvent('Event'); | ||||
| 		evt.initEvent('autosize:destroy', true, false); | ||||
| 		ta.dispatchEvent(evt); | ||||
| 	} | ||||
| 
 | ||||
| 	function update(ta) { | ||||
| 		if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return; | ||||
| 		var evt = document.createEvent('Event'); | ||||
| 		evt.initEvent('autosize:update', true, false); | ||||
| 		ta.dispatchEvent(evt); | ||||
| 	} | ||||
| 
 | ||||
| 	var autosize = null; | ||||
| 
 | ||||
| 	// Do nothing in Node.js environment and IE8 (or lower)
 | ||||
| 	if (typeof window === 'undefined' || typeof window.getComputedStyle !== 'function') { | ||||
| 		autosize = function (el) { | ||||
| 			return el; | ||||
| 		}; | ||||
| 		autosize.destroy = function (el) { | ||||
| 			return el; | ||||
| 		}; | ||||
| 		autosize.update = function (el) { | ||||
| 			return el; | ||||
| 		}; | ||||
| 	} else { | ||||
| 		autosize = function (el, options) { | ||||
| 			if (el) { | ||||
| 				Array.prototype.forEach.call(el.length ? el : [el], function (x) { | ||||
| 					return assign(x, options); | ||||
| 				}); | ||||
| 			} | ||||
| 			return el; | ||||
| 		}; | ||||
| 		autosize.destroy = function (el) { | ||||
| 			if (el) { | ||||
| 				Array.prototype.forEach.call(el.length ? el : [el], destroy); | ||||
| 			} | ||||
| 			return el; | ||||
| 		}; | ||||
| 		autosize.update = function (el) { | ||||
| 			if (el) { | ||||
| 				Array.prototype.forEach.call(el.length ? el : [el], update); | ||||
| 			} | ||||
| 			return el; | ||||
| 		}; | ||||
| 	} | ||||
| 
 | ||||
| 	module.exports = autosize; | ||||
| }); | ||||
							
								
								
									
										212
									
								
								js/components.js
									
										
									
									
									
								
							
							
						
						
									
										212
									
								
								js/components.js
									
										
									
									
									
								
							|  | @ -29667,3 +29667,215 @@ function emoji(){} | |||
| }).call(function(){ | ||||
| 	return this || (typeof window !== 'undefined' ? window : global); | ||||
| }()); | ||||
| 
 | ||||
| /*! | ||||
| 	Autosize 3.0.5 | ||||
| 	license: MIT | ||||
| 	http://www.jacklmoore.com/autosize
 | ||||
| */ | ||||
| (function (global, factory) { | ||||
| 	if (typeof define === 'function' && define.amd) { | ||||
| 		define(['exports', 'module'], factory); | ||||
| 	} else if (typeof exports !== 'undefined' && typeof module !== 'undefined') { | ||||
| 		factory(exports, module); | ||||
| 	} else { | ||||
| 		var mod = { | ||||
| 			exports: {} | ||||
| 		}; | ||||
| 		factory(mod.exports, mod); | ||||
| 		global.autosize = mod.exports; | ||||
| 	} | ||||
| })(this, function (exports, module) { | ||||
| 	'use strict'; | ||||
| 
 | ||||
| 	function assign(ta) { | ||||
| 		var _ref = arguments[1] === undefined ? {} : arguments[1]; | ||||
| 
 | ||||
| 		var _ref$setOverflowX = _ref.setOverflowX; | ||||
| 		var setOverflowX = _ref$setOverflowX === undefined ? true : _ref$setOverflowX; | ||||
| 		var _ref$setOverflowY = _ref.setOverflowY; | ||||
| 		var setOverflowY = _ref$setOverflowY === undefined ? true : _ref$setOverflowY; | ||||
| 
 | ||||
| 		if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || ta.hasAttribute('data-autosize-on')) return; | ||||
| 
 | ||||
| 		var heightOffset = null; | ||||
| 		var overflowY = 'hidden'; | ||||
| 
 | ||||
| 		function init() { | ||||
| 			var style = window.getComputedStyle(ta, null); | ||||
| 
 | ||||
| 			if (style.resize === 'vertical') { | ||||
| 				ta.style.resize = 'none'; | ||||
| 			} else if (style.resize === 'both') { | ||||
| 				ta.style.resize = 'horizontal'; | ||||
| 			} | ||||
| 
 | ||||
| 			if (style.boxSizing === 'content-box') { | ||||
| 				heightOffset = -(parseFloat(style.paddingTop) + parseFloat(style.paddingBottom)); | ||||
| 			} else { | ||||
| 				heightOffset = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth); | ||||
| 			} | ||||
| 
 | ||||
| 			update(); | ||||
| 		} | ||||
| 
 | ||||
| 		function changeOverflow(value) { | ||||
| 			{ | ||||
| 				// Chrome/Safari-specific fix:
 | ||||
| 				// When the textarea y-overflow is hidden, Chrome/Safari do not reflow the text to account for the space
 | ||||
| 				// made available by removing the scrollbar. The following forces the necessary text reflow.
 | ||||
| 				var width = ta.style.width; | ||||
| 				ta.style.width = '0px'; | ||||
| 				// Force reflow:
 | ||||
| 				/* jshint ignore:start */ | ||||
| 				ta.offsetWidth; | ||||
| 				/* jshint ignore:end */ | ||||
| 				ta.style.width = width; | ||||
| 			} | ||||
| 
 | ||||
| 			overflowY = value; | ||||
| 
 | ||||
| 			if (setOverflowY) { | ||||
| 				ta.style.overflowY = value; | ||||
| 			} | ||||
| 
 | ||||
| 			update(); | ||||
| 		} | ||||
| 
 | ||||
| 		function update() { | ||||
| 			var startHeight = ta.style.height; | ||||
| 			var htmlTop = document.documentElement.scrollTop; | ||||
| 			var bodyTop = document.body.scrollTop; | ||||
| 			var originalHeight = ta.style.height; | ||||
| 
 | ||||
| 			ta.style.height = 'auto'; | ||||
| 
 | ||||
| 			var endHeight = ta.scrollHeight + heightOffset; | ||||
| 
 | ||||
| 			if (ta.scrollHeight === 0) { | ||||
| 				// If the scrollHeight is 0, then the element probably has display:none or is detached from the DOM.
 | ||||
| 				ta.style.height = originalHeight; | ||||
| 				return; | ||||
| 			} | ||||
| 
 | ||||
| 			ta.style.height = endHeight + 'px'; | ||||
| 
 | ||||
| 			// prevents scroll-position jumping
 | ||||
| 			document.documentElement.scrollTop = htmlTop; | ||||
| 			document.body.scrollTop = bodyTop; | ||||
| 
 | ||||
| 			var style = window.getComputedStyle(ta, null); | ||||
| 
 | ||||
| 			if (style.height !== ta.style.height) { | ||||
| 				if (overflowY !== 'visible') { | ||||
| 					changeOverflow('visible'); | ||||
| 					return; | ||||
| 				} | ||||
| 			} else { | ||||
| 				if (overflowY !== 'hidden') { | ||||
| 					changeOverflow('hidden'); | ||||
| 					return; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			if (startHeight !== ta.style.height) { | ||||
| 				var evt = document.createEvent('Event'); | ||||
| 				evt.initEvent('autosize:resized', true, false); | ||||
| 				ta.dispatchEvent(evt); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		var destroy = (function (style) { | ||||
| 			window.removeEventListener('resize', update); | ||||
| 			ta.removeEventListener('input', update); | ||||
| 			ta.removeEventListener('keyup', update); | ||||
| 			ta.removeAttribute('data-autosize-on'); | ||||
| 			ta.removeEventListener('autosize:destroy', destroy); | ||||
| 
 | ||||
| 			Object.keys(style).forEach(function (key) { | ||||
| 				ta.style[key] = style[key]; | ||||
| 			}); | ||||
| 		}).bind(ta, { | ||||
| 			height: ta.style.height, | ||||
| 			resize: ta.style.resize, | ||||
| 			overflowY: ta.style.overflowY, | ||||
| 			overflowX: ta.style.overflowX, | ||||
| 			wordWrap: ta.style.wordWrap }); | ||||
| 
 | ||||
| 		ta.addEventListener('autosize:destroy', destroy); | ||||
| 
 | ||||
| 		// IE9 does not fire onpropertychange or oninput for deletions,
 | ||||
| 		// so binding to onkeyup to catch most of those events.
 | ||||
| 		// There is no way that I know of to detect something like 'cut' in IE9.
 | ||||
| 		if ('onpropertychange' in ta && 'oninput' in ta) { | ||||
| 			ta.addEventListener('keyup', update); | ||||
| 		} | ||||
| 
 | ||||
| 		window.addEventListener('resize', update); | ||||
| 		ta.addEventListener('input', update); | ||||
| 		ta.addEventListener('autosize:update', update); | ||||
| 		ta.setAttribute('data-autosize-on', true); | ||||
| 
 | ||||
| 		if (setOverflowY) { | ||||
| 			ta.style.overflowY = 'hidden'; | ||||
| 		} | ||||
| 		if (setOverflowX) { | ||||
| 			ta.style.overflowX = 'hidden'; | ||||
| 			ta.style.wordWrap = 'break-word'; | ||||
| 		} | ||||
| 
 | ||||
| 		init(); | ||||
| 	} | ||||
| 
 | ||||
| 	function destroy(ta) { | ||||
| 		if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return; | ||||
| 		var evt = document.createEvent('Event'); | ||||
| 		evt.initEvent('autosize:destroy', true, false); | ||||
| 		ta.dispatchEvent(evt); | ||||
| 	} | ||||
| 
 | ||||
| 	function update(ta) { | ||||
| 		if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return; | ||||
| 		var evt = document.createEvent('Event'); | ||||
| 		evt.initEvent('autosize:update', true, false); | ||||
| 		ta.dispatchEvent(evt); | ||||
| 	} | ||||
| 
 | ||||
| 	var autosize = null; | ||||
| 
 | ||||
| 	// Do nothing in Node.js environment and IE8 (or lower)
 | ||||
| 	if (typeof window === 'undefined' || typeof window.getComputedStyle !== 'function') { | ||||
| 		autosize = function (el) { | ||||
| 			return el; | ||||
| 		}; | ||||
| 		autosize.destroy = function (el) { | ||||
| 			return el; | ||||
| 		}; | ||||
| 		autosize.update = function (el) { | ||||
| 			return el; | ||||
| 		}; | ||||
| 	} else { | ||||
| 		autosize = function (el, options) { | ||||
| 			if (el) { | ||||
| 				Array.prototype.forEach.call(el.length ? el : [el], function (x) { | ||||
| 					return assign(x, options); | ||||
| 				}); | ||||
| 			} | ||||
| 			return el; | ||||
| 		}; | ||||
| 		autosize.destroy = function (el) { | ||||
| 			if (el) { | ||||
| 				Array.prototype.forEach.call(el.length ? el : [el], destroy); | ||||
| 			} | ||||
| 			return el; | ||||
| 		}; | ||||
| 		autosize.update = function (el) { | ||||
| 			if (el) { | ||||
| 				Array.prototype.forEach.call(el.length ? el : [el], update); | ||||
| 			} | ||||
| 			return el; | ||||
| 		}; | ||||
| 	} | ||||
| 
 | ||||
| 	module.exports = autosize; | ||||
| }); | ||||
|  | @ -59,6 +59,8 @@ | |||
| 
 | ||||
|         events: { | ||||
|             'submit .send': 'sendMessage', | ||||
|             'input .send-message': 'updateMessageFieldSize', | ||||
|             'keydown .send-message': 'updateMessageFieldSize', | ||||
|             'close': 'remove', | ||||
|             'click .destroy': 'destroyMessages', | ||||
|             'click .end-session': 'endSession', | ||||
|  | @ -161,7 +163,7 @@ | |||
| 
 | ||||
|         sendMessage: function(e) { | ||||
|             e.preventDefault(); | ||||
|             var input = this.$('.send input.send-message'); | ||||
|             var input = this.$('.send .send-message'); | ||||
|             var message = this.replace_colons(input.val()); | ||||
|             var convo = this.model; | ||||
| 
 | ||||
|  | @ -170,9 +172,11 @@ | |||
|                     convo.sendMessage(message, attachments); | ||||
|                 }); | ||||
|                 input.val(""); | ||||
|                 window.autosize(input); | ||||
|                 this.fileInput.deleteFiles(); | ||||
|             } | ||||
|         }, | ||||
| 
 | ||||
|         replace_colons: function(str) { | ||||
|             return str.replace(emoji.rx_colons, function(m){ | ||||
|                 var idx = m.substr(1, m.length-2); | ||||
|  | @ -187,6 +191,27 @@ | |||
| 
 | ||||
|         updateTitle: function() { | ||||
|             this.$('.conversation-title').text(this.model.getTitle()); | ||||
|         }, | ||||
| 
 | ||||
|         updateMessageFieldSize: function (event) { | ||||
|             var keyCode = event.which || event.keyCode; | ||||
| 
 | ||||
|             if (keyCode === 13) { | ||||
|                 // enter pressed - submit the form now
 | ||||
|                 return this.$('.bottom-bar form').submit(); | ||||
|             } | ||||
| 
 | ||||
|             var $messageField = this.$('.send-message'), | ||||
|                 $discussionContainer = this.$('.discussion-container'), | ||||
|                 $discussionContainerPrevHeight = $discussionContainer.outerHeight(), | ||||
|                 $bottomBar = this.$('.bottom-bar'), | ||||
|                 $bottomBarPrevHeight = $bottomBar.outerHeight(); | ||||
| 
 | ||||
|             window.autosize($messageField); | ||||
|             $bottomBar.outerHeight($messageField.outerHeight() + 1); | ||||
| 
 | ||||
|             var $bottomBarNewHeight = $bottomBar.outerHeight(); | ||||
|             $discussionContainer.outerHeight($discussionContainerPrevHeight - ($bottomBarNewHeight - $bottomBarPrevHeight)); | ||||
|         } | ||||
|     }); | ||||
| })(); | ||||
|  |  | |||
|  | @ -1,6 +1,4 @@ | |||
| .conversation { | ||||
|   padding: $header-height 0; | ||||
| 
 | ||||
|   .file-input .close { | ||||
|     top: -10px; | ||||
|   } | ||||
|  | @ -8,10 +6,18 @@ | |||
|   .conversation-title { | ||||
|     line-height: $header-height; | ||||
|   } | ||||
| 
 | ||||
|   #header { | ||||
|     position: inherit; | ||||
|   } | ||||
| 
 | ||||
|   .discussion-container { | ||||
|     height: calc(100% - 2 * #{$header-height}); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .conversation + .new-group-update-form, | ||||
| .conversation, .discussion-container, .message-list, .message-detail, .key-verification { | ||||
| .conversation, .message-list, .message-detail, .key-verification { | ||||
|   height: 100%; | ||||
| } | ||||
| 
 | ||||
|  | @ -29,6 +35,7 @@ | |||
|     padding: 0 1em; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .message-detail { | ||||
|   padding: $header-height 0 0; | ||||
|   background: $grey_l; | ||||
|  | @ -100,6 +107,7 @@ | |||
| .outgoing .sender { | ||||
|   display: none; | ||||
| } | ||||
| 
 | ||||
| .sender { | ||||
|   font-size: smaller; | ||||
|   opacity: 0.8; | ||||
|  | @ -110,10 +118,9 @@ | |||
| } | ||||
| 
 | ||||
| .entry.delivered .checkmark { | ||||
|     display: inline; | ||||
|   display: inline; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| .message-list { | ||||
|   margin: 0; | ||||
|   padding: 1em 0; | ||||
|  | @ -237,7 +244,9 @@ | |||
|         font-style: italic; | ||||
|       } | ||||
| 
 | ||||
|       &::before, &::after { display: none; } | ||||
|       &::before, &::after { | ||||
|         display: none; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|  | @ -308,6 +317,8 @@ | |||
| } | ||||
| 
 | ||||
| .bottom-bar { | ||||
|   $button-width: 36px; | ||||
| 
 | ||||
|   position: fixed; | ||||
|   bottom: 1; // offset 1 for window frame. | ||||
|   height: 36px; | ||||
|  | @ -315,7 +326,7 @@ | |||
|   border-top: 1px solid $grey_l; | ||||
|   background: white; | ||||
| 
 | ||||
|   button, input { | ||||
|   button, input, textarea { | ||||
|     color: $grey_d; | ||||
|   } | ||||
| 
 | ||||
|  | @ -323,7 +334,7 @@ | |||
|     position: absolute; | ||||
|     top: 0; | ||||
|     height: 100%; | ||||
|     width: 36px; | ||||
|     width: $button-width; | ||||
|     padding: 0; | ||||
|     border: 0; | ||||
|     outline: 0; | ||||
|  | @ -352,16 +363,19 @@ | |||
|     } | ||||
|   } | ||||
| 
 | ||||
|   form, input { | ||||
|   form, input, textarea { | ||||
|     height: 100%; | ||||
|   } | ||||
| 
 | ||||
|   input[type=textarea] { | ||||
|       display: block; | ||||
|       height: 100%; | ||||
|       border: 0; | ||||
|       outline: 0; | ||||
|       z-index: 5; | ||||
|   .send-message { | ||||
|     display: block; | ||||
|     width: calc(100% - 2 * #{$button-width} - 20px); | ||||
|     min-height: $header-height - 1px; | ||||
|     max-height: 100px; | ||||
|     padding: 10px; | ||||
|     border: 0; | ||||
|     outline: 0; | ||||
|     z-index: 5; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | @ -376,17 +390,20 @@ | |||
|   border-radius: 20px; | ||||
|   font-size: small; | ||||
| } | ||||
| 
 | ||||
| .confirmation-dialog { | ||||
|     position: absolute; | ||||
|     top: $header-height; | ||||
|     padding: 1em; | ||||
|     background: white; | ||||
|     border: solid 2px $blue; | ||||
|   position: absolute; | ||||
|   top: $header-height; | ||||
|   padding: 1em; | ||||
|   background: white; | ||||
|   border: solid 2px $blue; | ||||
| 
 | ||||
|     .message { text-align: center; } | ||||
|   .message { | ||||
|     text-align: center; | ||||
|   } | ||||
| 
 | ||||
|     button { | ||||
|       float: right; | ||||
|       margin-left: 10px; | ||||
|     } | ||||
|   button { | ||||
|     float: right; | ||||
|     margin-left: 10px; | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -130,16 +130,12 @@ button.back { | |||
|   margin-right: 10px; | ||||
|   cursor: pointer; | ||||
| 
 | ||||
|   .thumbnail { | ||||
|     width: 36px; | ||||
|     height: 36px; | ||||
|   } | ||||
|   .paperclip { | ||||
|     width: 36px; | ||||
|     height: 36px; | ||||
|     background: url('/images/paperclip.png') no-repeat; | ||||
|     height: 100%; | ||||
|     background: url('/images/paperclip.png') no-repeat center center; | ||||
|     background-size: 90%; | ||||
|     background-position: center 6px; | ||||
|     margin-top: 4px; | ||||
|   } | ||||
| 
 | ||||
|   input[type=file] { | ||||
|  |  | |||
|  | @ -116,15 +116,12 @@ button.back { | |||
|   position: relative; | ||||
|   margin-right: 10px; | ||||
|   cursor: pointer; } | ||||
|   .file-input .thumbnail { | ||||
|     width: 36px; | ||||
|     height: 36px; } | ||||
|   .file-input .paperclip { | ||||
|     width: 36px; | ||||
|     height: 36px; | ||||
|     background: url("/images/paperclip.png") no-repeat; | ||||
|     height: 100%; | ||||
|     background: url("/images/paperclip.png") no-repeat center center; | ||||
|     background-size: 90%; | ||||
|     background-position: center 6px; } | ||||
|     margin-top: 4px; } | ||||
|   .file-input input[type=file] { | ||||
|     display: none; | ||||
|     position: absolute; | ||||
|  | @ -427,15 +424,17 @@ input.search { | |||
| .conversations .unread .contact-details .last-timestamp { | ||||
|   font-weight: bold; } | ||||
| 
 | ||||
| .conversation { | ||||
|   padding: 36px 0; } | ||||
|   .conversation .file-input .close { | ||||
|     top: -10px; } | ||||
|   .conversation .conversation-title { | ||||
|     line-height: 36px; } | ||||
| .conversation .file-input .close { | ||||
|   top: -10px; } | ||||
| .conversation .conversation-title { | ||||
|   line-height: 36px; } | ||||
| .conversation #header { | ||||
|   position: inherit; } | ||||
| .conversation .discussion-container { | ||||
|   height: calc(100% - 2 * 36px); } | ||||
| 
 | ||||
| .conversation + .new-group-update-form, | ||||
| .conversation, .discussion-container, .message-list, .message-detail, .key-verification { | ||||
| .conversation, .message-list, .message-detail, .key-verification { | ||||
|   height: 100%; } | ||||
| 
 | ||||
| .key-verification { | ||||
|  | @ -666,7 +665,7 @@ input.search { | |||
|   width: calc(100% - 2px); | ||||
|   border-top: 1px solid #f3f3f3; | ||||
|   background: white; } | ||||
|   .bottom-bar button, .bottom-bar input { | ||||
|   .bottom-bar button, .bottom-bar input, .bottom-bar textarea { | ||||
|     color: #454545; } | ||||
|   .bottom-bar button { | ||||
|     position: absolute; | ||||
|  | @ -693,11 +692,14 @@ input.search { | |||
|     cursor: pointer; } | ||||
|     .bottom-bar .send-btn::before { | ||||
|       content: '+'; } | ||||
|   .bottom-bar form, .bottom-bar input { | ||||
|   .bottom-bar form, .bottom-bar input, .bottom-bar textarea { | ||||
|     height: 100%; } | ||||
|   .bottom-bar input[type=textarea] { | ||||
|   .bottom-bar .send-message { | ||||
|     display: block; | ||||
|     height: 100%; | ||||
|     width: calc(100% - 2 * 36px - 20px); | ||||
|     min-height: 35px; | ||||
|     max-height: 100px; | ||||
|     padding: 10px; | ||||
|     border: 0; | ||||
|     outline: 0; | ||||
|     z-index: 5; } | ||||
|  |  | |||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 adambar
				adambar