a89003b57a
* update stream.ts * https://github.com/misskey-dev/misskey/pull/7769#issuecomment-917542339 * fix lint * clean up? * add app * fix * nanka iroiro * wip * wip * fix lint * fix loginId * fix * refactor * refactor * remove follow action * clean up * Revert "remove follow action" This reverts commitdefbb41648
. * Revert "clean up" This reverts commitf94919cb9c
. * remove fetch specification * renoteの条件追加 * apiFetch => cli * bypass fetch? * fix * refactor: use path alias * temp: add submodule * remove submodule * enhane: unison-reloadに指定したパスに移動できるように * null * null * feat: ログインするアカウントのIDをクエリ文字列で指定する機能 * null * await? * rename * rename * Update read.ts * merge * get-note-summary * fix * swパッケージに * add missing packages * fix getNoteSummary * add webpack-cli * ✌️ * remove plugins * sw-inject分離したがテストしてない * fix notification.vue * remove a blank line * disconnect intersection observer * disconnect2 * fix notification.vue * remove a blank line * disconnect intersection observer * disconnect2 * fix * ✌️ * clean up config * typesを戻した * Update packages/client/src/components/notification.vue Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com> * disconnect * oops * Failed to load the script unexpectedly回避 sw.jsとlib.tsを分離してみた * truncate notification * Update packages/client/src/ui/_common_/common.vue Co-authored-by: syuilo <Syuilotan@yahoo.co.jp> * clean up * clean up * キャッシュ対策 * Truncate push notification message * クライアントがあったらストリームに接続しているということなので通知しない判定の位置を修正 * components/drive-file-thumbnail.vue * components/drive-select-dialog.vue * components/drive-window.vue * merge * fix * Service Workerのビルドにesbuildを使うようにする * return createEmptyNotification() * fix * i18n.ts * update * ✌️ * remove ts-loader * fix * fix * enhance: Service Workerを常に登録するように * pollEnded * URLをsw.jsに戻す * clean up * wip * wip * wip * wip * wip * wip * ✌️ * use import * fix * install rollup * use defineAsyncComponent. * fix emojilist * wip use defineAsyncComponent * popup(import -> popup(defineAsyncComponent(() => import * draggable? * fix init import * clean up * fix router * add comment * ✌️ * ✌️ * ✌️ * remove webpack * update vite * fix boot sequence * Revert "fix boot sequence" This reverts commite893dbf37a
. * revert boot import * never make two app div * ; * remove console.log * change clientEntry sequence * fix * Revert "fix" This reverts commit12741b3d89
. * fix * add comment https://github.com/misskey-dev/misskey/pull/8575#issuecomment-1114239210 * add log * add comment Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com> Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
118 lines
2.6 KiB
TypeScript
118 lines
2.6 KiB
TypeScript
import { defineAsyncComponent, Directive, ref } from 'vue';
|
|
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 show() {
|
|
if (!document.body.contains(this.el)) return;
|
|
if (this.promise) return;
|
|
|
|
const showing = ref(true);
|
|
|
|
popup(defineAsyncComponent(() => import('@/components/user-preview.vue')), {
|
|
showing,
|
|
q: this.user,
|
|
source: this.el
|
|
}, {
|
|
mouseover: () => {
|
|
window.clearTimeout(this.hideTimer);
|
|
},
|
|
mouseleave: () => {
|
|
window.clearTimeout(this.showTimer);
|
|
this.hideTimer = window.setTimeout(this.close, 500);
|
|
},
|
|
}, 'closed');
|
|
|
|
this.promise = {
|
|
cancel: () => {
|
|
showing.value = false;
|
|
}
|
|
};
|
|
|
|
this.checkTimer = window.setInterval(() => {
|
|
if (!document.body.contains(this.el)) {
|
|
window.clearTimeout(this.showTimer);
|
|
window.clearTimeout(this.hideTimer);
|
|
this.close();
|
|
}
|
|
}, 1000);
|
|
}
|
|
|
|
@autobind
|
|
private close() {
|
|
if (this.promise) {
|
|
window.clearInterval(this.checkTimer);
|
|
this.promise.cancel();
|
|
this.promise = null;
|
|
}
|
|
}
|
|
|
|
@autobind
|
|
private onMouseover() {
|
|
window.clearTimeout(this.showTimer);
|
|
window.clearTimeout(this.hideTimer);
|
|
this.showTimer = window.setTimeout(this.show, 500);
|
|
}
|
|
|
|
@autobind
|
|
private onMouseleave() {
|
|
window.clearTimeout(this.showTimer);
|
|
window.clearTimeout(this.hideTimer);
|
|
this.hideTimer = window.setTimeout(this.close, 500);
|
|
}
|
|
|
|
@autobind
|
|
private onClick() {
|
|
window.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);
|
|
window.clearInterval(this.checkTimer);
|
|
}
|
|
}
|
|
|
|
export default {
|
|
mounted(el: HTMLElement, binding, vn) {
|
|
if (binding.value == null) return;
|
|
|
|
// TODO: 新たにプロパティを作るのをやめMapを使う
|
|
// ただメモリ的には↓の方が省メモリかもしれないので検討中
|
|
const self = (el as any)._userPreviewDirective_ = {} as any;
|
|
|
|
self.preview = new UserPreview(el, binding.value);
|
|
},
|
|
|
|
unmounted(el, binding, vn) {
|
|
if (binding.value == null) return;
|
|
|
|
const self = el._userPreviewDirective_;
|
|
self.preview.detach();
|
|
}
|
|
} as Directive;
|