AniList - Activity Assistant

Script that speeds up Activity Making

当前为 2022-04-30 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name AniList - Activity Assistant
  3. // @namespace https://www.youtube.com/c/NurarihyonMaou/
  4. // @version 1.0
  5. // @description Script that speeds up Activity Making
  6. // @author NurarihyonMaou
  7. // @match https://anilist.co/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=anilist.co
  9. // @require https://code.jquery.com/jquery-3.6.0.js
  10. // @require https://code.jquery.com/ui/1.13.1/jquery-ui.js
  11. // @resource IMPORTED_CSS https://code.jquery.com/ui/1.13.1/themes/base/jquery-ui.css
  12. // @grant GM_getResourceText
  13. // @grant GM_addStyle
  14. // ==/UserScript==
  15.  
  16. const $ = window.jQuery;
  17. const x_csrf_token = $("head script:contains('window.al_token')").text().split(/[“"”]+/g)[1];
  18.  
  19. const imported_CSS = GM_getResourceText("IMPORTED_CSS");
  20. const category_Style = '.ui-autocomplete-category { font-weight: bold; padding: .2em .4em; margin: .8em 0 .2em;line-height: 1.5;}';
  21.  
  22. GM_addStyle(imported_CSS);
  23. GM_addStyle(category_Style);
  24.  
  25. let textArea;
  26. let autoComplete = [], selectedEntries = [];
  27. let allWords, currentWord, lastSearched, terms;
  28.  
  29. (function init() {
  30. textArea = document.getElementsByClassName("el-textarea__inner");
  31.  
  32. if (textArea.length > 0) {
  33.  
  34. $(textArea).after('<input type="hidden" id="testArea">');
  35.  
  36. function searchQuery(word) {
  37. var query = `
  38. query($search:String,$isAdult:Boolean){anime:Page(perPage:8){pageInfo{total}results:media(type:ANIME,isAdult:$isAdult,search:$search){id title{userPreferred}coverImage{medium}type format bannerImage isLicensed startDate{year}}}manga:Page(perPage:8){pageInfo{total}results:media(type:MANGA,isAdult:$isAdult,search:$search){id title{userPreferred}coverImage{medium}type format bannerImage isLicensed startDate{year}}}characters:Page(perPage:8){pageInfo{total}results:characters(search:$search){id name{userPreferred}image{medium}}}staff:Page(perPage:8){pageInfo{total}results:staff(search:$search){id primaryOccupations name{userPreferred}image{medium}}}studios:Page(perPage:13){pageInfo{total}results:studios(search:$search){id name}}users:Page(perPage:8){results:users(search:$search){id name avatar{medium}}}}
  39. `;
  40.  
  41. var variables = {
  42. search: word
  43. };
  44.  
  45. var url = 'https://anilist.co/graphql',
  46. options = {
  47. method: 'POST',
  48. headers: {
  49. 'Content-Type': 'application/json',
  50. 'Accept': 'application/json',
  51. "x-csrf-token": x_csrf_token
  52. },
  53. body: JSON.stringify({
  54. query: query,
  55. variables: variables
  56. })
  57. };
  58.  
  59. fetch(url, options).then(handleResponse)
  60. .then(handleData)
  61. .catch(handleError);
  62.  
  63. function handleResponse(response) {
  64. return response.json().then(function (json) {
  65. return response.ok ? json : Promise.reject(json);
  66. });
  67. }
  68.  
  69. function handleData(data) {
  70.  
  71. autoComplete = [];
  72.  
  73. $.each(data.data.anime.results, function (index, element) {
  74. autoComplete.push({ 'value': 'https://anilist.co/anime/' + element.id, 'label': element.title.userPreferred, 'category': 'Anime' });
  75. });
  76.  
  77. $.each(data.data.manga.results, function (index, element) {
  78. autoComplete.push({ 'value': 'https://anilist.co/manga/' + element.id, 'label': element.title.userPreferred, 'category': 'Manga' });
  79. });
  80.  
  81. $.each(data.data.characters.results, function (index, element) {
  82. autoComplete.push({ 'value': '[' + element.name.userPreferred + '](https://anilist.co/character/' + element.id + ")", 'label': element.name.userPreferred, 'category': 'Characters' });
  83. });
  84.  
  85. $.each(data.data.staff.results, function (index, element) {
  86. autoComplete.push({ 'value': '[' + element.name.userPreferred + '](https://anilist.co/staff/' + element.id + ")", 'label': element.name.userPreferred, 'category': 'Staff' });
  87. });
  88.  
  89. $.each(data.data.users.results, function (index, element) {
  90. autoComplete.push({ 'value': '@' + element.name, 'label': element.name, 'category': 'Users' });
  91. });
  92.  
  93. $.each(data.data.studios.results, function (index, element) {
  94. autoComplete.push({ 'value': '[' + element.name + '](https://anilist.co/studio/' + element.id + ")", 'label': element.name, 'category': 'Studios' });
  95. });
  96.  
  97. }
  98.  
  99. function handleError(error) {
  100. alert('Error, check console');
  101. console.error(error);
  102. }
  103. }
  104.  
  105. $.widget("custom.catcomplete", $.ui.autocomplete, {
  106. _create: function () {
  107. this._super();
  108. this.widget().menu("option", "items", "> :not(.ui-autocomplete-category)");
  109. },
  110. _renderMenu: function (ul, items) {
  111. var that = this,
  112. currentCategory = "";
  113. $.each(items, function (index, item) {
  114. var li;
  115. if (item.category != currentCategory) {
  116. ul.append("<li class='ui-autocomplete-category'>" + item.category + "</li>");
  117. currentCategory = item.category;
  118. }
  119. li = that._renderItemData(ul, item);
  120. if (item.category) {
  121. li.attr("aria-label", item.category + " : " + item.label);
  122. }
  123. });
  124. }
  125. });
  126.  
  127. $(textArea).on('input', function () {
  128. allWords = $(this).val().split(' ');
  129. currentWord = allWords[allWords.length - 1];
  130. if (currentWord.length > 2 && lastSearched != currentWord) {
  131. searchQuery(currentWord);
  132. lastSearched = currentWord;
  133. }
  134. });
  135.  
  136. function split(val) {
  137. return val.split(/ \s*/);
  138. }
  139.  
  140. function extractLast(term) {
  141. return split(term).pop();
  142. }
  143.  
  144. $(textArea).catcomplete({
  145. delay: 500,
  146. minLength: 3,
  147. source: function (request, response) {
  148. response($.ui.autocomplete.filter(
  149. autoComplete, extractLast(request.term)));
  150. },
  151. focus: function () {
  152. return false;
  153. },
  154. select: function (event, ui) {
  155. terms = split(this.value);
  156. terms.pop();
  157. terms.push(ui.item.value);
  158. terms.push("");
  159. this.value = terms.join(" ");
  160. selectedEntries.push(ui.item.label);
  161. autoComplete = [];
  162. return false;
  163. }
  164. });
  165.  
  166. } else {
  167. setTimeout(init, 0);
  168. }
  169. })();