summaryrefslogtreecommitdiff
path: root/source/features/open-all-conversations.tsx
blob: f6ba04b8b30e327b7af9167a028a1121e2c0767a (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
import React from 'dom-chef';
import {$$, elementExists} from 'select-dom';
import delegate, {DelegateEvent} from 'delegate-it';
import elementReady from 'element-ready';
import * as pageDetect from 'github-url-detection';

import features from '../feature-manager.js';
import openTabs from '../helpers/open-tabs.js';
import {attachElements} from '../helpers/attach-element.js';

function getUrlFromItem(issue: Element): string {
	return issue
		.closest('.js-issue-row')!
		.querySelector('a.js-navigation-open')!
		.href;
}

const issueListSelector = pageDetect.isGlobalIssueOrPRList()
	? '#js-issues-toolbar div'
	: 'div[aria-label="Issues"][role="group"]';

function onButtonClick(event: DelegateEvent<MouseEvent, HTMLButtonElement>): void {
	const onlySelected = event.delegateTarget.closest('.table-list-triage');
	const issues = $$(`${issueListSelector} .js-issue-row`)
		// TODO: Use conditional :has(:checked) instead
		.filter(issue => onlySelected ? elementExists(':checked', issue) : true);
	void openTabs(issues.map(issue => getUrlFromItem(issue)));
}

async function hasMoreThanOneConversation(): Promise<boolean> {
	return Boolean(await elementReady('.js-issue-row + .js-issue-row', {waitForChildren: false}));
}

async function init(signal: AbortSignal): Promise<void | false> {
	attachElements('.table-list-header-toggle:not(.states)', {
		prepend: anchor => (
			<button
				type="button"
				className="btn-link rgh-open-all-conversations px-2"
			>
				{anchor.closest('.table-list-triage') ? 'Open selected' : 'Open all'}
			</button>
		)},
	);

	delegate('button.rgh-open-all-conversations', 'click', onButtonClick, {signal});
}

void features.add(import.meta.url, {
	asLongAs: [
		hasMoreThanOneConversation,
	],
	include: [
		pageDetect.isIssueOrPRList,
	],
	exclude: [
		pageDetect.isGlobalIssueOrPRList,
	],
	init,
}, {
	include: [
		pageDetect.isGlobalIssueOrPRList,
	],
	init,
});

/*

Test URLs:

- Global: https://github.com/issues
- Repo: https://github.com/sindresorhus/refined-github/pulls
- Nothing to open: https://github.com/fregante/empty/pulls

*/