summaryrefslogtreecommitdiff
path: root/source/features/rgh-sponsor-button.tsx
blob: 22ce2d6925de8550431289eb4b5592c641d9d57f (plain) (blame)
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*

                                                       ..       :
                    .                  .               .   .  .
      .           .                .               .. .  .  *
             *          .                    ..        .
                           .             .     . :  .   .    .  .
            .                         .   .  .  .   .
                                         . .  *:. . .
.                                 .  .   . .. .         .
                         .     . .  . ...    .    .
       .              .  .  . .    . .  . .
                        .    .     . ...   ..   .       .               .
                 .  .    . *.   . .
    .                   :.  .           .
                 .   .    .    .
             .  .  .    ./|\
            .  .. :.    . |             .               .
     .   ... .            |
 .    :.  . .   *.        |     .               .
   .  *.             You are here.
 . .    .               .             *.                         .

*/
import cache from 'webext-storage-cache';
import select from 'select-dom';
import delegate from 'delegate-it';
import * as pageDetect from 'github-url-detection';

import features from '.';
import {getRepo, getUsername} from '../github-helpers';

async function wiggleWiggleWiggle(): Promise<void> {
	await cache.set('did-it-wiggle', 'yup', {days: 7});
	select('#sponsor-button-repo')?.animate({
		transform: [
			'none',
			'rotate(-2deg) scale(1.05)',
			'rotate(2deg) scale(1.1)',
			'rotate(-2deg) scale(1.1)',
			'rotate(2deg) scale(1.1)',
			'rotate(-2deg) scale(1.1)',
			'rotate(2deg) scale(1.05)',
			'none',
		],
	}, 600);
}

async function suchLove({delegateTarget}: delegate.Event): Promise<void> {
	const heart = select('.octicon-heart', delegateTarget);

	// .closest ensures that clicking the lightbox’ background doesn't also trigger the animation
	if (!heart || delegateTarget.closest('details[open]')) {
		return;
	}

	const rect = heart.getBoundingClientRect();
	const love = heart.cloneNode(true);
	Object.assign(love.style, {
		position: 'fixed',
		zIndex: '9999999999',
		left: `${rect.x}px`,
		top: `${rect.y}px`,
	});

	document.body.append(love);

	await love.animate({
		transform: [
			'translateZ(0)',
			'translateZ(0) scale(80)',
		],
		opacity: [
			1,
			0,
		],
	}, {
		duration: 600,
		easing: 'ease-out',
	}).finished;

	love.remove(); // 💔
}

async function handleNewIssue(): Promise<false> {
	if (getRepo()!.owner !== getUsername() && !await cache.get('did-it-wiggle')) {
		select('.btn-primary[href$="/issues/new/choose"], .btn-primary[href$="/issues/new"]')
			?.addEventListener('mouseenter', wiggleWiggleWiggle, {
				once: true,
			});
	}

	return false;
}

function handleSponsorButton(): void {
	delegate(document, '#sponsor-button-repo, #sponsor-profile-button, [aria-label^="Sponsor @"]', 'click', suchLove);
}

void features.add(__filebasename, {
	include: [
		pageDetect.isIssue,
		pageDetect.isRepoIssueList,
	],
	deduplicate: 'has-rgh-inner',
	init: handleNewIssue,
}, {
	include: [
		pageDetect.isRepo,
		pageDetect.isUserProfile,
		pageDetect.isOrganizationProfile,
	],
	init: handleSponsorButton,
});