✌️
This commit is contained in:
		
							parent
							
								
									83fde7c131
								
							
						
					
					
						commit
						3e91159bc3
					
				
					 5 changed files with 43 additions and 29 deletions
				
			
		| 
						 | 
					@ -78,6 +78,7 @@
 | 
				
			||||||
		"@types/websocket": "0.0.37",
 | 
							"@types/websocket": "0.0.37",
 | 
				
			||||||
		"accesses": "2.5.0",
 | 
							"accesses": "2.5.0",
 | 
				
			||||||
		"animejs": "2.2.0",
 | 
							"animejs": "2.2.0",
 | 
				
			||||||
 | 
							"autosize": "4.0.0",
 | 
				
			||||||
		"autwh": "0.0.1",
 | 
							"autwh": "0.0.1",
 | 
				
			||||||
		"bcryptjs": "2.4.3",
 | 
							"bcryptjs": "2.4.3",
 | 
				
			||||||
		"body-parser": "1.18.2",
 | 
							"body-parser": "1.18.2",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,7 @@ import * as pictograph from 'pictograph';
 | 
				
			||||||
import contains from '../../../common/scripts/contains';
 | 
					import contains from '../../../common/scripts/contains';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
	props: ['type', 'q', 'textarea', 'complete', 'close'],
 | 
						props: ['type', 'q', 'textarea', 'complete', 'close', 'x', 'y'],
 | 
				
			||||||
	data() {
 | 
						data() {
 | 
				
			||||||
		return {
 | 
							return {
 | 
				
			||||||
			fetching: true,
 | 
								fetching: true,
 | 
				
			||||||
| 
						 | 
					@ -37,6 +37,27 @@ export default Vue.extend({
 | 
				
			||||||
			return (this.$refs.suggests as Element).children;
 | 
								return (this.$refs.suggests as Element).children;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						updated() {
 | 
				
			||||||
 | 
							//#region 位置調整
 | 
				
			||||||
 | 
							const margin = 32;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (this.x + this.$el.offsetWidth > window.innerWidth - margin) {
 | 
				
			||||||
 | 
								this.$el.style.left = (this.x - this.$el.offsetWidth) + 'px';
 | 
				
			||||||
 | 
								this.$el.style.marginLeft = '-16px';
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								this.$el.style.left = this.x + 'px';
 | 
				
			||||||
 | 
								this.$el.style.marginLeft = '0';
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (this.y + this.$el.offsetHeight > window.innerHeight - margin) {
 | 
				
			||||||
 | 
								this.$el.style.top = (this.y - this.$el.offsetHeight) + 'px';
 | 
				
			||||||
 | 
								this.$el.style.marginTop = '0';
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								this.$el.style.top = this.y + 'px';
 | 
				
			||||||
 | 
								this.$el.style.marginTop = 'calc(1em + 8px)';
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							//#endregion
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
	mounted() {
 | 
						mounted() {
 | 
				
			||||||
		this.textarea.addEventListener('keydown', this.onKeydown);
 | 
							this.textarea.addEventListener('keydown', this.onKeydown);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -136,7 +157,7 @@ export default Vue.extend({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style lang="stylus" scoped>
 | 
					<style lang="stylus" scoped>
 | 
				
			||||||
.mk-autocomplete
 | 
					.mk-autocomplete
 | 
				
			||||||
	position absolute
 | 
						position fixed
 | 
				
			||||||
	z-index 65535
 | 
						z-index 65535
 | 
				
			||||||
	margin-top calc(1em + 8px)
 | 
						margin-top calc(1em + 8px)
 | 
				
			||||||
	overflow hidden
 | 
						overflow hidden
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
<div class="mk-messaging-form">
 | 
					<div class="mk-messaging-form">
 | 
				
			||||||
	<textarea v-model="text" @keypress="onKeypress" @paste="onPaste" placeholder="%i18n:common.input-message-here%" v-autocomplete></textarea>
 | 
						<textarea v-model="text" ref="textarea" @keypress="onKeypress" @paste="onPaste" placeholder="%i18n:common.input-message-here%" v-autocomplete></textarea>
 | 
				
			||||||
	<div class="file" v-if="file">{{ file.name }}</div>
 | 
						<div class="file" v-if="file">{{ file.name }}</div>
 | 
				
			||||||
	<mk-uploader ref="uploader"/>
 | 
						<mk-uploader ref="uploader"/>
 | 
				
			||||||
	<button class="send" @click="send" :disabled="sending" title="%i18n:common.send%">
 | 
						<button class="send" @click="send" :disabled="sending" title="%i18n:common.send%">
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
import Vue from 'vue';
 | 
					import Vue from 'vue';
 | 
				
			||||||
 | 
					import * as autosize from 'autosize';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
	props: ['user'],
 | 
						props: ['user'],
 | 
				
			||||||
	data() {
 | 
						data() {
 | 
				
			||||||
| 
						 | 
					@ -27,6 +29,9 @@ export default Vue.extend({
 | 
				
			||||||
			sending: false
 | 
								sending: false
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						mounted() {
 | 
				
			||||||
 | 
							autosize(this.$refs.textarea);
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		onPaste(e) {
 | 
							onPaste(e) {
 | 
				
			||||||
			const data = e.clipboardData;
 | 
								const data = e.clipboardData;
 | 
				
			||||||
| 
						 | 
					@ -93,6 +98,7 @@ export default Vue.extend({
 | 
				
			||||||
		height 64px
 | 
							height 64px
 | 
				
			||||||
		margin 0
 | 
							margin 0
 | 
				
			||||||
		padding 8px
 | 
							padding 8px
 | 
				
			||||||
 | 
							resize none
 | 
				
			||||||
		font-size 1em
 | 
							font-size 1em
 | 
				
			||||||
		color #000
 | 
							color #000
 | 
				
			||||||
		outline none
 | 
							outline none
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,6 @@
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
	<footer>
 | 
						<footer>
 | 
				
			||||||
		<div ref="notifications" class="notifications"></div>
 | 
							<div ref="notifications" class="notifications"></div>
 | 
				
			||||||
		<div class="grippie" title="%i18n:common.tags.mk-messaging-room.resize-form%"></div>
 | 
					 | 
				
			||||||
		<x-form :user="user"/>
 | 
							<x-form :user="user"/>
 | 
				
			||||||
	</footer>
 | 
						</footer>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
| 
						 | 
					@ -316,16 +315,4 @@ export default Vue.extend({
 | 
				
			||||||
					line-height 32px
 | 
										line-height 32px
 | 
				
			||||||
					font-size 16px
 | 
										font-size 16px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		> .grippie
 | 
					 | 
				
			||||||
			height 10px
 | 
					 | 
				
			||||||
			margin-top -10px
 | 
					 | 
				
			||||||
			background transparent
 | 
					 | 
				
			||||||
			cursor ns-resize
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			&:hover
 | 
					 | 
				
			||||||
				//background rgba(0, 0, 0, 0.1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			&:active
 | 
					 | 
				
			||||||
				//background rgba(0, 0, 0, 0.2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,6 +82,15 @@ class Autocomplete {
 | 
				
			||||||
		// 既に開いているサジェストは閉じる
 | 
							// 既に開いているサジェストは閉じる
 | 
				
			||||||
		this.close();
 | 
							this.close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							//#region サジェストを表示すべき位置を計算
 | 
				
			||||||
 | 
							const caretPosition = getCaretCoordinates(this.textarea, this.textarea.selectionStart);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const rect = this.textarea.getBoundingClientRect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const x = rect.left + caretPosition.left - this.textarea.scrollLeft;
 | 
				
			||||||
 | 
							const y = rect.top + caretPosition.top - this.textarea.scrollTop;
 | 
				
			||||||
 | 
							//#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// サジェスト要素作成
 | 
							// サジェスト要素作成
 | 
				
			||||||
		this.suggestion = new MkAutocomplete({
 | 
							this.suggestion = new MkAutocomplete({
 | 
				
			||||||
			propsData: {
 | 
								propsData: {
 | 
				
			||||||
| 
						 | 
					@ -89,22 +98,12 @@ class Autocomplete {
 | 
				
			||||||
				complete: this.complete,
 | 
									complete: this.complete,
 | 
				
			||||||
				close: this.close,
 | 
									close: this.close,
 | 
				
			||||||
				type: type,
 | 
									type: type,
 | 
				
			||||||
				q: q
 | 
									q: q,
 | 
				
			||||||
 | 
									x,
 | 
				
			||||||
 | 
									y
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}).$mount();
 | 
							}).$mount();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		//#region サジェストを表示すべき位置を計算
 | 
					 | 
				
			||||||
		const caretPosition = getCaretCoordinates(this.textarea, this.textarea.selectionStart);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		const rect = this.textarea.getBoundingClientRect();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		const x = rect.left + window.pageXOffset + caretPosition.left - this.textarea.scrollLeft;
 | 
					 | 
				
			||||||
		const y = rect.top + window.pageYOffset + caretPosition.top - this.textarea.scrollTop;
 | 
					 | 
				
			||||||
		//#endregion
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		this.suggestion.$el.style.left = x + 'px';
 | 
					 | 
				
			||||||
		this.suggestion.$el.style.top = y + 'px';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// 要素追加
 | 
							// 要素追加
 | 
				
			||||||
		document.body.appendChild(this.suggestion.$el);
 | 
							document.body.appendChild(this.suggestion.$el);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue