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