KING RUSSIA | Testers QA

Для сотрудников "Контроля Качества"

  1. // ==UserScript==
  2. // @name KING RUSSIA | Testers QA
  3. // @namespace https://forum.kingrussia.com
  4. // @version 1.40
  5. // @description Для сотрудников "Контроля Качества"
  6. // @author KING RUSSIA
  7. // @match https://forum.kingrussia.com/index.php*
  8. // @include https://forum.kingrussia.com/index.php
  9. // @grant none
  10. // @license MIT
  11. // @collaborator Basis of Antonio Carrizo and consultant Rosenfeld
  12. // @icon https://icons.iconarchive.com/icons/thesquid.ink/free-flat-sample/128/support-icon.png
  13. // ==/UserScript==
  14.  
  15. (function () {
  16. 'use strict';
  17. const PAQUA_PREFIX = 16; // Prefix that will be set when thread solved
  18. const PAQA_PREFIX = 15; // Prefix that will be set when thread solved
  19. const COMMAND_PREFIX = 9; // Prefix that will be set when thread send to project team
  20. const WATCHED_PREFIX = 4;
  21. const buttons = [
  22. {
  23. title: '----------------------------------- Работа с темами на отдел тестирование --------------------------------'
  24. },
  25. {
  26. title: 'На рассмотрение',
  27. content:
  28. '[CENTER][size=15px][font=Georgia]Приветствую, уважаемый(-ая) {{ user.mention }}![/size][/font][/CENTER]<br><br>' +
  29. "[CENTER][size=15px][font=Georgia][COLOR=rgb(255,255,255)]Ваша тема взята [COLOR=rgb(255,215,0)][B]на рассмотрение.[/B][/color][/size][/font][/CENTER]<br><br>" +
  30. '[CENTER][size=15px][font=Georgia][COLOR=rgb(0,255,255)]Проверено контролем качества![/color][/size][/font][/CENTER]',
  31. prefix: PAQA_PREFIX,
  32. status: true,
  33. },
  34. {
  35. title: 'Обратно тех. спецу',
  36. content:
  37. '[CENTER][size=15px][font=Georgia]Приветствую, уважаемый(-ая) {{ user.mention }}![/size][/font][/CENTER]<br><br>' +
  38. "[CENTER][size=15px][font=Georgia][COLOR=rgb(255,255,255)]К сожалению ваша тема не относится в [COLOR=rgb(0,255,255)][B]отдел тестирования.[/B][/color][/size][/font][/CENTER]<br><br>" +
  39. '[CENTER][size=15px][font=Georgia]Передано - [COLOR=rgb(255,69,0)][B]Техническому специалисту.[/B][/color][/size][/font][/CENTER]<br>' +
  40. '[CENTER][size=15px][font=Georgia][COLOR=rgb(0,255,255)]Проверено контролем качества![/color][/size][/font][/CENTER]',
  41. prefix: WATCHED_PREFIX,
  42. status: true,
  43. },
  44.  
  45. {
  46. title: 'Нарушение правил раздела',
  47. content:
  48. '[CENTER][size=15px][font=Georgia]Приветствую, уважаемый(-ая) {{ user.mention }}![/size][/font][/CENTER]<br><br>' +
  49. "[CENTER][size=15px][font=Georgia]Пожалуйста, убедительная просьба, ознакомиться с назначением данного раздела в котором Вы создали тему, так как Ваш запрос никоим образом не относится к технической проблеме.[/size][/font][/CENTER]<br><br>" +
  50. '[CENTER][size=15px][font=Georgia][COLOR=rgb(255,0,0)][B]Отказано, закрыто.[/B][/color][/size][/font][/CENTER]<br>' +
  51. '[CENTER][size=15px][font=Georgia][COLOR=rgb(0,255,255)]Проверено контролем качества![/color][/size][/font][/CENTER]',
  52. prefix: PAQUA_PREFIX,
  53. status: true,
  54. },
  55. {
  56. title: 'Краш / вылет',
  57. content:
  58. '[CENTER][size=15px][font=Georgia]Приветствую, уважаемый(-ая) {{ user.mention }}![/size][/font][/CENTER]<br><br>' +
  59. "[CENTER][size=15px][font=Georgia]В том случае, если Вы вылетели из игры во время игрового процесса (произошел краш), в обязательном порядке необходимо обратиться в тех. поддержку в VK или Telegram:[/size][/font][/CENTER]<br><br>" +
  60. '[CENTER][size=15px][font=Georgia]VK - https://vk.com/kingcrmphelp | Telegram - https://t.me/tehkingrussia_bot[/size][/font][/CENTER]<br><br>' +
  61. '[CENTER][size=15px][font=Georgia][COLOR=rgb(255,215,0)]Решено, обратитесь в тех. поддержку, связи указанны выше.[/color][/size][/font][/CENTER]' +
  62. '[CENTER][size=15px][font=Georgia][COLOR=rgb(0,255,255)]Проверено контролем качества![/color][/size][/font][/CENTER]',
  63. prefix: PAQUA_PREFIX,
  64. status: false,
  65. },
  66. {
  67. title: 'Дублирование темы',
  68. content:
  69. '[CENTER][size=15px][font=Georgia]Приветствую, уважаемый(-ая) {{ user.mention }}![/size][/font][/CENTER]<br><br>' +
  70. "[CENTER][size=15px][font=Georgia]Ответ уже был дан в подобной теме. Пожалуйста, прекратите создавать идентичные или похожие темы - иначе Ваш форумный аккаунт может быть [COLOR=rgb(255,0,0)][B]заблокирован.[/B][/color][/size][/font][/CENTER]<br><br>" +
  71. '[CENTER][size=15px][font=Georgia][COLOR=rgb(255,0,0)][B]Закрыто.[/B][/color][/size][/font][/CENTER]<br>' +
  72. '[CENTER][size=15px][font=Georgia][COLOR=rgb(0,255,255)]Проверено контролем качества![/color][/size][/font][/CENTER]',
  73. prefix: PAQUA_PREFIX,
  74. status: false,
  75. },
  76. {
  77. title: 'Проблема будет исправлена',
  78. content:
  79. '[CENTER][size=15px][font=Georgia]Приветствую, уважаемый(-ая) {{ user.mention }}![/size][/font][/CENTER]<br><br>' +
  80. "[CENTER][size=15px][font=Georgia]Данная недоработка / ошибка будет [COLOR=rgb(0,255,0)][B]проверена и исправлена.[/B] [COLOR=rgb(255,255,255)]Спасибо за обращение, мы ценим Ваш огромный вклад в наш проект![/color][/size][/font][/CENTER]<br><br>" +
  81. '[CENTER][size=15px][font=Georgia][COLOR=rgb(0,255,0)][B]Рассмотрено.[/B][/color][/size][/font][/CENTER]<br>' +
  82. '[CENTER][size=15px][font=Georgia][COLOR=rgb(0,255,255)]Проверено контролем качества![/color][/size][/font][/CENTER]',
  83. prefix: PAQUA_PREFIX,
  84. status: false,
  85. },
  86. {
  87. title: 'Уточните суть проблемы',
  88. content:
  89. '[CENTER][size=15px][font=Georgia]Приветствую, уважаемый(-ая) {{ user.mention }}![/size][/font][/CENTER]<br><br>' +
  90. "[CENTER][size=15px][font=Georgia]Уточните более подробно суть вашего обращения.[/size][/font][/CENTER]<br><br>" +
  91. '[CENTER][size=15px][font=Georgia][COLOR=rgb(255,0,0)][B]Закрыто.[/B][/color][/size][/font][/CENTER]<br>' +
  92. '[CENTER][size=15px][font=Georgia][COLOR=rgb(0,255,255)]Проверено контролем качества![/color][/size][/font][/CENTER]',
  93. prefix: PAQUA_PREFIX,
  94. status: false,
  95. },
  96. {
  97. title: 'Известно о проблеме',
  98. content:
  99. '[CENTER][size=15px][font=Georgia]Приветствую, уважаемый(-ая) {{ user.mention }}![/size][/font][/CENTER]<br><br>' +
  100. "[CENTER][size=15px][font=Georgia]После проверки вашей темы, стало ясно, что данная ошибка/недоработка уже известна нам.[/size][/font][/CENTER]<br>" +
  101. '[CENTER][size=15px][font=Georgia]В скором времени баг будет исправлен.[/size][/font][/CENTER]<br><br>' +
  102. '[CENTER][size=15px][font=Georgia][COLOR=rgb(0,255,0)][B]Рассмотрено.[/B][/color][/size][/font][/CENTER]<br>' +
  103. '[CENTER][size=15px][font=Georgia][COLOR=rgb(0,255,255)]Проверено контролем качества![/color][/size][/font][/CENTER]',
  104. prefix: PAQUA_PREFIX,
  105. status: false,
  106. },
  107. {
  108. title: 'Передано на тестирование',
  109. content:
  110. '[CENTER][size=15px][font=Georgia]Приветствую, уважаемый(-ая) {{ user.mention }}![/size][/font][/CENTER]<br><br>' +
  111. "[CENTER][size=15px][font=Georgia]Благодарим за уведомление о недоработке. Ваша тема находится в [COLOR=rgb(0,255,255)][B]процессе тестирования.[/B][/color][/size][/font]<br><br>" +
  112. '[CENTER][size=15px][font=Georgia][COLOR=rgb(255,215,0)][B]На рассмотрении.[/B][/size][/font][/CENTER]<br>' +
  113. '[CENTER][size=15px][font=Georgia][COLOR=rgb(0,255,255)]Проверено контролем качества![/color][/size][/font][/CENTER]',
  114. prefix: PAQUA_PREFIX,
  115. status: false,
  116. },
  117. {
  118. title: 'Команде проекта',
  119. content:
  120. '[CENTER][size=15px][font=Georgia]Приветствую, уважаемый(-ая) {{ user.mention }}![/size][/font][/CENTER]<br><br>' +
  121. "[CENTER][size=15px][font=Georgia][COLOR=rgb(255,255,255)]Ваша тема закреплена и находится [COLOR=rgb(255,215,0)][B]на рассмотрении.[/B] [COLOR=rgb(255,255,255)]Пожалуйста, ожидайте выноса вердикта [COLOR=rgb(255,215,0)][B]команды проекта.[/B][/color][/size][/font][/CENTER]<br><br>" +
  122. '[CENTER][size=15px][font=Georgia][COLOR=rgb(255,255,255)]Создавать новые темы с данной проблемой — [COLOR=rgb(255,0,0)][B]не нужно[/B][COLOR=rgb(255,255,255)], ожидайте ответа в данной теме. Если проблема решится - [COLOR=rgb(0,255,0)][B]Вы всегда можете уведомить нас о ее решении.[/B][/color][/size][/font][/CENTER]<br><br>' +
  123. '[CENTER][size=15px][font=Georgia][COLOR=rgb(0,255,255)]Проверено контролем качества![/color][/size][/font][/CENTER]',
  124. prefix: COMMAND_PREFIX,
  125. status: true,
  126. },
  127. {
  128. title: 'Недостаточно доказательств',
  129. content:
  130. '[CENTER][size=15px][font=Georgia]Приветствую, уважаемый(-ая) {{ user.mention }}![/size][/font][/CENTER]<br><br>' +
  131. "[CENTER][size=15px][font=Georgia][COLOR=rgb(255,255,255)]Без доказательств (в частности скриншоты или видео)[COLOR=rgb(255,0,0)] [B]– решить проблему не получится.[/B] [COLOR=rgb(255,255,255)]Если доказательства найдутся - создайте новую тему, приложив доказательства с фото-хостинга yapx.ru или imgur.com<br><br>" +
  132. '[CENTER][size=15px][font=Georgia][COLOR=rgb(0,255,0)][B]Рассмотрено, [COLOR=rgb(255,0,0)]закрыто.[/B][/color][/size][/font][/CENTER]<br>' +
  133. '[CENTER][size=15px][font=Georgia][COLOR=rgb(0,255,255)]Проверено контролем качества![/color][/size][/font][/CENTER]',
  134. prefix: PAQUA_PREFIX,
  135. status: false,
  136. },
  137. ];
  138.  
  139.  
  140. $(document).ready(() => {
  141. // Загрузка скрипта для обработки шаблонов
  142. $('body').append('<script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"></script>');
  143.  
  144.  
  145. // Добавление кнопок при загрузке страницы
  146. addButton('На рассмотрении', 'pin');
  147. addButton('КП', 'teamProject');
  148. addButton('Отказано', 'unaccept');
  149. addButton('Рассмотрено', 'watched');
  150. addButton('Решено', 'accepted');
  151. addButton('Закрыто', 'closed');
  152. addButton('Ответы', 'selectAnswer');
  153.  
  154. // Поиск информации о теме
  155. const threadData = getThreadData();
  156.  
  157. $('button#pin').click(() => editThreadData(RASSMOTRENNO_PREFIX, true));
  158. $('button#accepted').click(() => editThreadData(ACCEPT_PREFIX, false));
  159. $('button#Ga').click(() => editThreadData(GA_PREFIX, true));
  160. $('button#teamProject').click(() => editThreadData(COMMAND_PREFIX, true));
  161. $('button#unaccept').click(() => editThreadData(UNACCEPT_PREFIX, false));
  162. $('button#Texy').click(() => editThreadData(TEX_PREFIX, false));
  163. $('button#Zakrito').click(() => editThreadData(CLOSE_PREFIX, false));
  164.  
  165. $(`button#selectAnswer`).click(() => {
  166. XF.alert(buttonsMarkup(buttons), null, 'Выберите ответ:');
  167. buttons.forEach((btn, id) => {
  168. if (id > 0) {
  169. $(`button#answers-${id}`).click(() => pasteContent(id, threadData, true));
  170. }
  171. else {
  172. $(`button#answers-${id}`).click(() => pasteContent(id, threadData, false));
  173. }
  174. });
  175. });
  176. });
  177. function addButton(name, id) {
  178. $('.button--icon--reply').before(
  179. `<button type="button" class="button rippleButton" id="${id}" style="margin: 3px;">${name}</button>`,
  180. );
  181. }
  182.  
  183. function buttonsMarkup(buttons) {
  184. return `<div class="select_answer">${buttons
  185. .map(
  186. (btn, i) =>
  187. `<button id="answers-${i}" class="button--primary button ` +
  188. `rippleButton" style="margin:5px"><span class="button-text">${btn.title}</span></button>`,
  189. )
  190. .join('')}</div>`;
  191. }
  192.  
  193. function pasteContent(id, data = {}, send = false) {
  194. const template = Handlebars.compile(buttons[id].content);
  195. if ($('.fr-element.fr-view p').text() === '') $('.fr-element.fr-view p').empty();
  196.  
  197. $('span.fr-placeholder').empty();
  198. $('div.fr-element.fr-view p').append(template(data));
  199. $('a.overlay-titleCloser').trigger('click');
  200.  
  201. if (send == true) {
  202. editThreadData(buttons[id].prefix, buttons[id].status);
  203. $('.button--icon.button--icon--reply.rippleButton').trigger('click');
  204. }
  205. }
  206.  
  207.  
  208. function getThreadData() {
  209. const authorID = $('a.username')[0].attributes['data-user-id'].nodeValue;
  210. const authorName = $('a.username').html();
  211. const hours = new Date().getHours();
  212. return {
  213. user: {
  214. id: authorID,
  215. name: authorName,
  216. mention: `[USER=${authorID}]${authorName}[/USER]`,
  217. },
  218. greeting: () =>
  219. 4 < hours && hours <= 11 ?
  220. 'Доброе утро' :
  221. 11 < hours && hours <= 15 ?
  222. 'Добрый день' :
  223. 15 < hours && hours <= 21 ?
  224. 'Добрый вечер' :
  225. 'Доброй ночи',
  226. };
  227. }
  228.  
  229. function editThreadData(prefix, pin = false) {
  230. // Получаем заголовок темы, так как он необходим при запросе
  231. const threadTitle = $('.p-title-value')[0].lastChild.textContent;
  232.  
  233. if(pin == false){
  234. fetch(`${document.URL}edit`, {
  235. method: 'POST',
  236. body: getFormData({
  237. prefix_id: prefix,
  238. title: threadTitle,
  239. _xfToken: XF.config.csrf,
  240. _xfRequestUri: document.URL.split(XF.config.url.fullBase)[1],
  241. _xfWithData: 1,
  242. _xfResponseType: 'json',
  243. }),
  244. }).then(() => location.reload());
  245. } else {
  246. fetch(`${document.URL}edit`, {
  247. method: 'POST',
  248. body: getFormData({
  249. prefix_id: prefix,
  250. title: threadTitle,
  251. pin: 1,
  252. _xfToken: XF.config.csrf,
  253. _xfRequestUri: document.URL.split(XF.config.url.fullBase)[1],
  254. _xfWithData: 1,
  255. _xfResponseType: 'json',
  256. }),
  257. }).then(() => location.reload());
  258. }
  259.  
  260.  
  261.  
  262.  
  263. if(pin == false){
  264. fetch(`${document.URL}edit`, {
  265. method: 'POST',
  266. body: getFormData({
  267. prefix_id: prefix,
  268. title: threadTitle,
  269. _xfToken: XF.config.csrf,
  270. _xfRequestUri: document.URL.split(XF.config.url.fullBase)[1],
  271. _xfWithData: 1,
  272. _xfResponseType: 'json',
  273. }),
  274. }).then(() => location.reload());
  275. } else {
  276. fetch(`${document.URL}edit`, {
  277. method: 'POST',
  278. body: getFormData({
  279. prefix_id: prefix,
  280. title: threadTitle,
  281. pin: 1,
  282. _xfToken: XF.config.csrf,
  283. _xfRequestUri: document.URL.split(XF.config.url.fullBase)[1],
  284. _xfWithData: 1,
  285. _xfResponseType: 'json',
  286. }),
  287. }).then(() => location.reload());
  288. }
  289.  
  290.  
  291. function moveThread(prefix, type) {
  292. // Получаем заголовок темы, так как он необходим при запросе
  293. const threadTitle = $('.p-title-value')[0].lastChild.textContent;
  294.  
  295. fetch(`${document.URL}move`, {
  296. method: 'POST',
  297. body: getFormData({
  298. prefix_id: prefix,
  299. title: threadTitle,
  300. target_node_id: type,
  301. redirect_type: 'none',
  302. notify_watchers: 1,
  303. starter_alert: 1,
  304. starter_alert_reason: "",
  305. _xfToken: XF.config.csrf,
  306. _xfRequestUri: document.URL.split(XF.config.url.fullBase)[1],
  307. _xfWithData: 1,
  308. _xfResponseType: 'json',
  309. }),
  310. }).then(() => location.reload());
  311. }
  312.  
  313. function getFormData(data) {
  314. const formData = new FormData();
  315. Object.entries(data).forEach(i => formData.append(i[0], i[1]));
  316. return formData;
  317. }
  318. }
  319. })();