summaryrefslogtreecommitdiff
path: root/src/web/app/desktop/mixins/user-preview.js
blob: 3f483beb3a8d7a33c1fa343fe97dc4265b1f23bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import * as riot from 'riot';

riot.mixin('user-preview', {
	init: function() {
		const scan = () => {
			this.root.querySelectorAll('[data-user-preview]:not([data-user-preview-attached])')
				.forEach(attach.bind(this));
		};
		this.on('mount', scan);
		this.on('updated', scan);
	}
});

function attach(el) {
	el.setAttribute('data-user-preview-attached', true);

	const user = el.getAttribute('data-user-preview');
	let tag = null;
	let showTimer = null;
	let hideTimer = null;

	el.addEventListener('mouseover', () => {
		clearTimeout(showTimer);
		clearTimeout(hideTimer);
		showTimer = setTimeout(show, 500);
	});

	el.addEventListener('mouseleave', () => {
		clearTimeout(showTimer);
		clearTimeout(hideTimer);
		hideTimer = setTimeout(close, 500);
	});

	this.on('unmount', () => {
		clearTimeout(showTimer);
		clearTimeout(hideTimer);
		close();
	});

	const show = () => {
		if (tag) return;
		const preview = document.createElement('mk-user-preview');
		const rect = el.getBoundingClientRect();
		const x = rect.left + el.offsetWidth + window.pageXOffset;
		const y = rect.top + window.pageYOffset;
		preview.style.top = y + 'px';
		preview.style.left = x + 'px';
		preview.addEventListener('mouseover', () => {
			clearTimeout(hideTimer);
		});
		preview.addEventListener('mouseleave', () => {
			clearTimeout(showTimer);
			hideTimer = setTimeout(close, 500);
		});
		tag = riot.mount(document.body.appendChild(preview), {
			user: user
		})[0];
	};

	const close = () => {
		if (tag) {
			tag.close();
			tag = null;
		}
	};
}