Files
misskey/src/client/scripts/user-preview.ts
syuilo e427f2160a wip
2020-09-21 14:42:16 +09:00

90 lines
1.8 KiB
TypeScript

import autobind from 'autobind-decorator';
import { popup } from '@/os';
export class UserPreview {
private el;
private user;
private showTimer;
private hideTimer;
private checkTimer;
private promise;
constructor(el, user) {
this.el = el;
this.user = user;
this.attach();
}
@autobind
private async show() {
if (!document.body.contains(this.el)) return;
if (this.promise) return;
this.promise = popup(await import('@/components/user-preview.vue'), {
user: this.user,
source: this.el
}, {
mouseover: () => {
clearTimeout(this.hideTimer);
},
mouseleave: () => {
clearTimeout(this.showTimer);
this.hideTimer = setTimeout(this.close, 500);
},
});
this.checkTimer = setInterval(() => {
if (!document.body.contains(this.el)) {
clearTimeout(this.showTimer);
clearTimeout(this.hideTimer);
this.close();
}
}, 1000);
}
@autobind
private close() {
if (this.promise) {
clearInterval(this.checkTimer);
this.promise.cancel();
this.promise = null;
}
}
@autobind
private onMouseover() {
clearTimeout(this.showTimer);
clearTimeout(this.hideTimer);
this.showTimer = setTimeout(this.show, 500);
}
@autobind
private onMouseleave() {
clearTimeout(this.showTimer);
clearTimeout(this.hideTimer);
this.hideTimer = setTimeout(this.close, 500);
}
@autobind
private onClick() {
clearTimeout(this.showTimer);
this.close();
}
@autobind
public attach() {
this.el.addEventListener('mouseover', this.onMouseover);
this.el.addEventListener('mouseleave', this.onMouseleave);
this.el.addEventListener('click', this.onClick);
}
@autobind
public detach() {
this.el.removeEventListener('mouseover', this.onMouseover);
this.el.removeEventListener('mouseleave', this.onMouseleave);
this.el.removeEventListener('click', this.onClick);
clearInterval(this.checkTimer);
}
}