blob: 4fb3af8864028ccbfbb07e3222391a09a36847fd [file] [log] [blame]
Adrià Vilanova Martínez462280f2021-08-07 22:59:02 +02001import {CCApi} from '../common/api.js';
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +02002import {parseUrl} from '../common/commonUtils.js';
3import {getAuthUser} from '../common/communityConsoleUtils.js';
avm99963f5923962020-12-07 16:44:37 +01004
5function recursiveParentElement(el, tag) {
6 while (el !== document.documentElement) {
7 el = el.parentNode;
8 if (el.tagName == tag) return el;
9 }
10 return undefined;
11}
12
13// Source:
14// https://stackoverflow.com/questions/33063774/communication-from-an-injected-script-to-the-content-script-with-a-response
15var contentScriptRequest = (function() {
16 var requestId = 0;
17 var prefix = 'TWPT-batchlock-generic';
18
19 function sendRequest(data) {
20 var id = requestId++;
21
22 return new Promise(function(resolve, reject) {
23 var listener = function(evt) {
24 if (evt.source === window && evt.data && evt.data.prefix === prefix &&
25 evt.data.requestId == id) {
26 // Deregister self
27 window.removeEventListener('message', listener);
28 resolve(evt.data.data);
29 }
30 };
31
32 window.addEventListener('message', listener);
33
34 var payload = {data, id, prefix};
35
36 window.dispatchEvent(
37 new CustomEvent('TWPT_sendRequest', {detail: payload}));
38 });
39 }
40
41 return {sendRequest: sendRequest};
42})();
43
44function enableEndButtons() {
45 var buttons = document.querySelectorAll(
46 '.pane[pane-id="default-1"] footer[data-footer-id="1"] material-button');
47 buttons.forEach(btn => {
48 btn.classList.remove('is-disabled');
49 });
50}
51
52function addLogEntry(success, action, url, threadId, errDetails = null) {
53 var p1 = contentScriptRequest.sendRequest({
54 action: 'geti18nMessage',
55 msg: 'inject_lockdialog_log_entry_beginning',
56 placeholders: [threadId],
57 });
58
59 var p2 = contentScriptRequest.sendRequest({
60 action: 'geti18nMessage',
61 msg: 'inject_lockdialog_log_entry_' + (success ? 'success' : 'error') +
62 '_' + action,
63 placeholders: [errDetails],
64 });
65
66 Promise.all([p1, p2]).then(strings => {
67 var log = document.getElementById('TWPT-lock-log');
68 var logEntry = document.createElement('p');
69 logEntry.classList.add(
70 'TWPT-log-entry', 'TWPT-log-entry--' + (success ? 'success' : 'error'));
71
72 var a = document.createElement('a');
73 a.href = url;
74 a.target = '_blank';
75 a.textContent = strings[0];
76
77 var end = document.createTextNode(': ' + strings[1]);
78
79 logEntry.append(a, end);
80 log.append(logEntry);
81 });
82}
83
84function lockThreads(action) {
85 var modal = document.querySelector('.pane[pane-id="default-1"]');
86 modal.querySelector('footer[data-footer-id="0"]').classList.add('is-hidden');
87 modal.querySelector('footer[data-footer-id="1"]')
88 .classList.remove('is-hidden');
89
90 var checkboxes = document.querySelectorAll(
91 '.thread-group material-checkbox[aria-checked="true"]');
92
93 var p = document.createElement('p');
94 p.style.textAlign = 'center';
95
96 var progress = document.createElement('progress');
97 progress.max = checkboxes.length;
98 progress.value = 0;
99
100 p.append(progress);
101
102 var log = document.createElement('div');
103 log.id = 'TWPT-lock-log';
104 log.classList.add('TWPT-log');
105
106 modal.querySelector('main').textContent = '';
107 modal.querySelector('main').append(p, log);
108
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200109 var authuser = getAuthUser();
avm999638d3b4ca2020-12-08 13:21:52 +0100110
avm99963f5923962020-12-07 16:44:37 +0100111 checkboxes.forEach(checkbox => {
avm99963d08c37e2022-09-25 20:41:58 +0200112 var url = recursiveParentElement(checkbox, 'EC-THREAD-SUMMARY')
113 .querySelector('a.header-content')
114 .href;
avm99963f5923962020-12-07 16:44:37 +0100115 var thread = parseUrl(url);
116 if (thread === false) {
117 console.error('Fatal error: thread URL ' + url + ' could not be parsed.');
118 return;
119 }
avm99963d08c37e2022-09-25 20:41:58 +0200120 CCApi(
121 'SetThreadAttribute', {
122 1: thread.forum,
123 2: thread.thread,
124 3: (action == 'lock' ? 1 : 2),
125 },
126 /* authenticated = */ true, authuser)
Adrià Vilanova Martínez462280f2021-08-07 22:59:02 +0200127 .then(() => {
avm99963f5923962020-12-07 16:44:37 +0100128 addLogEntry(true, action, url, thread.thread);
129 })
130 .catch(err => {
131 console.error(
132 'An error occurred while locking thread ' + url + ': ' + err);
133 addLogEntry(false, action, url, thread.thread, err);
134 })
Adrià Vilanova Martínez462280f2021-08-07 22:59:02 +0200135 .then(() => {
avm99963f5923962020-12-07 16:44:37 +0100136 progress.value = parseInt(progress.value) + 1;
137 if (progress.value == progress.getAttribute('max'))
138 enableEndButtons();
139 });
140 });
141}
142
143window.addEventListener('message', e => {
144 if (e.source === window && e.data && e.data.prefix === 'TWPT-batchlock' &&
145 e.data.action) {
146 switch (e.data.action) {
147 case 'lock':
148 case 'unlock':
Adrià Vilanova Martínez462280f2021-08-07 22:59:02 +0200149 console.debug('Performing action ' + e.data.action);
avm99963f5923962020-12-07 16:44:37 +0100150 lockThreads(e.data.action);
151 break;
152
153 default:
154 console.error(
155 'Action \'' + e.data.action +
156 '\' unknown to TWPT-batchlock receiver.');
157 }
158 }
159});