chore: improve reaction picker behaviour

This commit is contained in:
syuilo 2021-02-28 02:22:53 +09:00
parent 36d6eb85b4
commit d9710cb5c5
2 changed files with 63 additions and 61 deletions

View file

@ -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];

View file

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