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; } }); }