chore: improve reaction picker behaviour
This commit is contained in:
		
							parent
							
								
									764a158cd7
								
							
						
					
					
						commit
						7674a62d40
					
				|  | @ -69,71 +69,78 @@ export default defineComponent({ | |||
| 	mounted() { | ||||
| 		this.$watch('src', () => { | ||||
| 			this.fixed = getFixedContainer(this.src) != null; | ||||
| 			this.$nextTick(() => { | ||||
| 				this.align(); | ||||
| 			}); | ||||
| 		}, { immediate: true }); | ||||
| 
 | ||||
| 		this.$nextTick(() => { | ||||
| 			const popover = this.$refs.content as any; | ||||
| 
 | ||||
| 			// TODO: ResizeObserver無くしたい | ||||
| 			new ResizeObserver((entries, observer) => { | ||||
| 				if (!this.popup) return; | ||||
| 
 | ||||
| 				const rect = this.src.getBoundingClientRect(); | ||||
| 				 | ||||
| 				const width = popover.offsetWidth; | ||||
| 				const height = popover.offsetHeight; | ||||
| 
 | ||||
| 				let left; | ||||
| 				let top; | ||||
| 
 | ||||
| 				if (this.srcCenter) { | ||||
| 					const x = rect.left + (this.fixed ? 0 : window.pageXOffset) + (this.src.offsetWidth / 2); | ||||
| 					const y = rect.top + (this.fixed ? 0 : window.pageYOffset) + (this.src.offsetHeight / 2); | ||||
| 					left = (x - (width / 2)); | ||||
| 					top = (y - (height / 2)); | ||||
| 				} else { | ||||
| 					const x = rect.left + (this.fixed ? 0 : window.pageXOffset) + (this.src.offsetWidth / 2); | ||||
| 					const y = rect.top + (this.fixed ? 0 : window.pageYOffset) + this.src.offsetHeight; | ||||
| 					left = (x - (width / 2)); | ||||
| 					top = y; | ||||
| 				} | ||||
| 
 | ||||
| 				if (this.fixed) { | ||||
| 					if (left + width > window.innerWidth) { | ||||
| 						left = window.innerWidth - width; | ||||
| 					} | ||||
| 
 | ||||
| 					if (top + height > window.innerHeight) { | ||||
| 						top = window.innerHeight - height; | ||||
| 					} | ||||
| 				} else { | ||||
| 					if (left + width - window.pageXOffset > window.innerWidth) { | ||||
| 						left = window.innerWidth - width + window.pageXOffset - 1; | ||||
| 					} | ||||
| 
 | ||||
| 					if (top + height - window.pageYOffset > window.innerHeight) { | ||||
| 						top = window.innerHeight - height + window.pageYOffset - 1; | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				if (top < 0) { | ||||
| 					top = 0; | ||||
| 				} | ||||
| 
 | ||||
| 				if (left < 0) { | ||||
| 					left = 0; | ||||
| 				} | ||||
| 
 | ||||
| 				if (top > rect.top + (this.fixed ? 0 : window.pageYOffset)) { | ||||
| 					this.transformOrigin = 'center top'; | ||||
| 				} | ||||
| 
 | ||||
| 				popover.style.left = left + 'px'; | ||||
| 				popover.style.top = top + 'px'; | ||||
| 				this.align(); | ||||
| 			}).observe(popover); | ||||
| 		}); | ||||
| 	}, | ||||
| 	methods: { | ||||
| 		align() { | ||||
| 			if (!this.popup) return; | ||||
| 
 | ||||
| 			const popover = this.$refs.content as any; | ||||
| 
 | ||||
| 			const rect = this.src.getBoundingClientRect(); | ||||
| 			 | ||||
| 			const width = popover.offsetWidth; | ||||
| 			const height = popover.offsetHeight; | ||||
| 
 | ||||
| 			let left; | ||||
| 			let top; | ||||
| 
 | ||||
| 			if (this.srcCenter) { | ||||
| 				const x = rect.left + (this.fixed ? 0 : window.pageXOffset) + (this.src.offsetWidth / 2); | ||||
| 				const y = rect.top + (this.fixed ? 0 : window.pageYOffset) + (this.src.offsetHeight / 2); | ||||
| 				left = (x - (width / 2)); | ||||
| 				top = (y - (height / 2)); | ||||
| 			} else { | ||||
| 				const x = rect.left + (this.fixed ? 0 : window.pageXOffset) + (this.src.offsetWidth / 2); | ||||
| 				const y = rect.top + (this.fixed ? 0 : window.pageYOffset) + this.src.offsetHeight; | ||||
| 				left = (x - (width / 2)); | ||||
| 				top = y; | ||||
| 			} | ||||
| 
 | ||||
| 			if (this.fixed) { | ||||
| 				if (left + width > window.innerWidth) { | ||||
| 					left = window.innerWidth - width; | ||||
| 				} | ||||
| 
 | ||||
| 				if (top + height > window.innerHeight) { | ||||
| 					top = window.innerHeight - height; | ||||
| 				} | ||||
| 			} else { | ||||
| 				if (left + width - window.pageXOffset > window.innerWidth) { | ||||
| 					left = window.innerWidth - width + window.pageXOffset - 1; | ||||
| 				} | ||||
| 
 | ||||
| 				if (top + height - window.pageYOffset > window.innerHeight) { | ||||
| 					top = window.innerHeight - height + window.pageYOffset - 1; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			if (top < 0) { | ||||
| 				top = 0; | ||||
| 			} | ||||
| 
 | ||||
| 			if (left < 0) { | ||||
| 				left = 0; | ||||
| 			} | ||||
| 
 | ||||
| 			if (top > rect.top + (this.fixed ? 0 : window.pageYOffset)) { | ||||
| 				this.transformOrigin = 'center top'; | ||||
| 			} | ||||
| 
 | ||||
| 			popover.style.left = left + 'px'; | ||||
| 			popover.style.top = top + 'px'; | ||||
| 		}, | ||||
| 
 | ||||
| 		childRendered() { | ||||
| 			// モーダルコンテンツにマウスボタンが押され、コンテンツ外でマウスボタンが離されたときにモーダルバックグラウンドクリックと判定させないためにマウスイベントを監視しフラグ管理する | ||||
| 			const content = this.$refs.content.children[0]; | ||||
|  |  | |||
|  | @ -360,16 +360,12 @@ export async function openEmojiPicker(src?: HTMLElement, opts, initialTextarea: | |||
| let reactionPicker = null; | ||||
| export async function pickReaction(src: HTMLElement, chosen, closed) { | ||||
| 	if (reactionPicker) { | ||||
| 		if (reactionPicker.opening) return; | ||||
| 
 | ||||
| 		reactionPicker.opening = true; | ||||
| 		reactionPicker.src.value = src; | ||||
| 		reactionPicker.manualShowing.value = true; | ||||
| 		reactionPicker.chosen = chosen; | ||||
| 		reactionPicker.closed = closed; | ||||
| 	} else { | ||||
| 		reactionPicker = { | ||||
| 			opening: true, | ||||
| 			src: ref(src), | ||||
| 			manualShowing: ref(true), | ||||
| 			chosen, closed | ||||
|  | @ -388,7 +384,6 @@ export async function pickReaction(src: HTMLElement, chosen, closed) { | |||
| 			closed: () => { | ||||
| 				reactionPicker.src.value = null; | ||||
| 				reactionPicker.closed(); | ||||
| 				reactionPicker.opening = false; | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue