From 7674a62d40b7d4eec82387a1157e48da10c2f312 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 28 Feb 2021 02:22:53 +0900 Subject: [PATCH] chore: improve reaction picker behaviour --- src/client/components/ui/modal.vue | 119 +++++++++++++++-------------- src/client/os.ts | 5 -- 2 files changed, 63 insertions(+), 61 deletions(-) diff --git a/src/client/components/ui/modal.vue b/src/client/components/ui/modal.vue index 1c8ae6390..03be43707 100644 --- a/src/client/components/ui/modal.vue +++ b/src/client/components/ui/modal.vue @@ -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]; diff --git a/src/client/os.ts b/src/client/os.ts index 9fafb6db4..e97c2d7ba 100644 --- a/src/client/os.ts +++ b/src/client/os.ts @@ -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; } }); }