blob: 20bea1362716b76f5d89aa0cfc301809db2e169b [file] [log] [blame]
Adrià Vilanova Martínez462280f2021-08-07 22:59:02 +02001import {CCApi} from '../common/api.js';
Adrià Vilanova Martínez54964a52022-10-26 23:53:29 +02002import {parseUrl, recursiveParentElement} from '../common/commonUtils.js';
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +02003import {getAuthUser} from '../common/communityConsoleUtils.js';
Adrià Vilanova Martínez08a760b2023-02-03 18:47:30 +01004import {kModalPaneSelector} from '../contentScripts/communityConsole/batchLock.js';
avm99963f5923962020-12-07 16:44:37 +01005
avm99963f5923962020-12-07 16:44:37 +01006// Source:
7// https://stackoverflow.com/questions/33063774/communication-from-an-injected-script-to-the-content-script-with-a-response
8var contentScriptRequest = (function() {
9 var requestId = 0;
10 var prefix = 'TWPT-batchlock-generic';
11
12 function sendRequest(data) {
13 var id = requestId++;
14
15 return new Promise(function(resolve, reject) {
16 var listener = function(evt) {
17 if (evt.source === window && evt.data && evt.data.prefix === prefix &&
18 evt.data.requestId == id) {
19 // Deregister self
20 window.removeEventListener('message', listener);
21 resolve(evt.data.data);
22 }
23 };
24
25 window.addEventListener('message', listener);
26
27 var payload = {data, id, prefix};
28
29 window.dispatchEvent(
30 new CustomEvent('TWPT_sendRequest', {detail: payload}));
31 });
32 }
33
34 return {sendRequest: sendRequest};
35})();
36
37function enableEndButtons() {
Adrià Vilanova Martínez08a760b2023-02-03 18:47:30 +010038 var buttons =
39 document.querySelector(kModalPaneSelector)
40 .querySelectorAll('footer[data-footer-id="1"] material-button');
avm99963f5923962020-12-07 16:44:37 +010041 buttons.forEach(btn => {
42 btn.classList.remove('is-disabled');
43 });
44}
45
46function addLogEntry(success, action, url, threadId, errDetails = null) {
47 var p1 = contentScriptRequest.sendRequest({
48 action: 'geti18nMessage',
49 msg: 'inject_lockdialog_log_entry_beginning',
50 placeholders: [threadId],
51 });
52
53 var p2 = contentScriptRequest.sendRequest({
54 action: 'geti18nMessage',
55 msg: 'inject_lockdialog_log_entry_' + (success ? 'success' : 'error') +
56 '_' + action,
57 placeholders: [errDetails],
58 });
59
60 Promise.all([p1, p2]).then(strings => {
61 var log = document.getElementById('TWPT-lock-log');
62 var logEntry = document.createElement('p');
63 logEntry.classList.add(
64 'TWPT-log-entry', 'TWPT-log-entry--' + (success ? 'success' : 'error'));
65
66 var a = document.createElement('a');
67 a.href = url;
68 a.target = '_blank';
69 a.textContent = strings[0];
70
71 var end = document.createTextNode(': ' + strings[1]);
72
73 logEntry.append(a, end);
74 log.append(logEntry);
75 });
76}
77
78function lockThreads(action) {
Adrià Vilanova Martínez08a760b2023-02-03 18:47:30 +010079 var modal = document.querySelector(kModalPaneSelector);
avm99963f5923962020-12-07 16:44:37 +010080 modal.querySelector('footer[data-footer-id="0"]').classList.add('is-hidden');
81 modal.querySelector('footer[data-footer-id="1"]')
82 .classList.remove('is-hidden');
83
84 var checkboxes = document.querySelectorAll(
85 '.thread-group material-checkbox[aria-checked="true"]');
86
87 var p = document.createElement('p');
88 p.style.textAlign = 'center';
89
90 var progress = document.createElement('progress');
91 progress.max = checkboxes.length;
92 progress.value = 0;
93
94 p.append(progress);
95
96 var log = document.createElement('div');
97 log.id = 'TWPT-lock-log';
98 log.classList.add('TWPT-log');
99
100 modal.querySelector('main').textContent = '';
101 modal.querySelector('main').append(p, log);
102
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200103 var authuser = getAuthUser();
avm999638d3b4ca2020-12-08 13:21:52 +0100104
avm99963f5923962020-12-07 16:44:37 +0100105 checkboxes.forEach(checkbox => {
avm99963d08c37e2022-09-25 20:41:58 +0200106 var url = recursiveParentElement(checkbox, 'EC-THREAD-SUMMARY')
107 .querySelector('a.header-content')
108 .href;
avm99963f5923962020-12-07 16:44:37 +0100109 var thread = parseUrl(url);
110 if (thread === false) {
111 console.error('Fatal error: thread URL ' + url + ' could not be parsed.');
112 return;
113 }
avm99963d08c37e2022-09-25 20:41:58 +0200114 CCApi(
115 'SetThreadAttribute', {
116 1: thread.forum,
117 2: thread.thread,
118 3: (action == 'lock' ? 1 : 2),
119 },
120 /* authenticated = */ true, authuser)
Adrià Vilanova Martínez462280f2021-08-07 22:59:02 +0200121 .then(() => {
avm99963f5923962020-12-07 16:44:37 +0100122 addLogEntry(true, action, url, thread.thread);
123 })
124 .catch(err => {
125 console.error(
126 'An error occurred while locking thread ' + url + ': ' + err);
127 addLogEntry(false, action, url, thread.thread, err);
128 })
Adrià Vilanova Martínez462280f2021-08-07 22:59:02 +0200129 .then(() => {
avm99963f5923962020-12-07 16:44:37 +0100130 progress.value = parseInt(progress.value) + 1;
131 if (progress.value == progress.getAttribute('max'))
132 enableEndButtons();
133 });
134 });
135}
136
137window.addEventListener('message', e => {
138 if (e.source === window && e.data && e.data.prefix === 'TWPT-batchlock' &&
139 e.data.action) {
140 switch (e.data.action) {
141 case 'lock':
142 case 'unlock':
Adrià Vilanova Martínez462280f2021-08-07 22:59:02 +0200143 console.debug('Performing action ' + e.data.action);
avm99963f5923962020-12-07 16:44:37 +0100144 lockThreads(e.data.action);
145 break;
146
147 default:
148 console.error(
149 'Action \'' + e.data.action +
150 '\' unknown to TWPT-batchlock receiver.');
151 }
152 }
153});