NHentai Improved

Partially fade/remove non-english, HQ thumbnails, mark as read, subs, etc.

Verze ze dne 24. 03. 2020. Zobrazit nejnovější verzi.

  1. // ==UserScript==
  2. // @name NHentai Improved
  3. // @namespace Hentiedup
  4. // @version 1.5.1
  5. // @description Partially fade/remove non-english, HQ thumbnails, mark as read, subs, etc.
  6. // @author Hentiedup
  7. // @match https://nhentai.net/*
  8. // @require https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
  9. // @grant GM_setValue
  10. // @grant GM_getValue
  11. // @grant GM_deleteValue
  12. // @grant GM_listValues
  13. // @icon https://i.imgur.com/1lihxY2.png
  14. // ==/UserScript==
  15.  
  16. (function() {
  17. 'use strict';
  18.  
  19. //YOU SHOULD NOT TOUCH THE SETTINGS HERE. THEY ARE NOW AVAILABLE ON THE SITE IN THE PROFILE SETTINGS
  20.  
  21. //== non-english settings ==//
  22. var remove_non_english = GM_getValue("remove_non_english", false);
  23. var partially_fade_all_non_english = GM_getValue("partially_fade_all_non_english", true);
  24. var non_english_fade_opacity = GM_getValue("non_english_fade_opacity", 0.3);
  25.  
  26. //== browse sections ==//
  27. var browse_thumbnail_width = GM_getValue("browse_thumbnail_width", 250);
  28. var browse_thumnail_container_width = GM_getValue("browse_thumnail_container_width", 1350);
  29. var load_high_quality_browse_thumbnails = GM_getValue("load_high_quality_browse_thumbnails", true);
  30.  
  31. //== comic pages view ==//
  32. var pages_thumbnail_width = GM_getValue("pages_thumbnail_width", 300);
  33. var pages_thumnail_container_width = GM_getValue("pages_thumnail_container_width", 1350);
  34. var load_high_quality_pages_thumbnails = GM_getValue("load_high_quality_pages_thumbnails", true);
  35.  
  36. //== mark as read system ==//
  37. var mark_as_read_system_enabled = GM_getValue("mark_as_read_system_enabled", true);
  38. var marked_as_read_fade_opacity = GM_getValue("marked_as_read_fade_opacity", 0.3);
  39. var read_tag_font_size = GM_getValue("read_tag_font_size", 15);
  40.  
  41. //== subscription system ==//
  42. var subscription_system_enabled = GM_getValue("subscription_system_enabled", true);
  43.  
  44. //== version grouping system ==//
  45. var version_grouping_enabled = GM_getValue("version_grouping_enabled", true);
  46. var version_grouping_filter_brackets = GM_getValue("version_grouping_filter_brackets", false);
  47. var auto_group_on_page_comics = GM_getValue("auto_group_on_page_comics", true);
  48. var flagEn = "https://i.imgur.com/vSnHmmi.gif";
  49. var flagJp = "https://i.imgur.com/GlArpuS.gif";
  50. var flagCh = "https://i.imgur.com/7B55DYm.gif";
  51.  
  52. //================= Getting arrays ready =================//
  53. if(true) {
  54. if(subscription_system_enabled) {
  55. var SubArray = [];
  56. var SubArrayString = GM_getValue("SubArrayString", null);
  57. if(SubArrayString) { SubArray = JSON.parse(SubArrayString); }
  58. }
  59.  
  60. if(mark_as_read_system_enabled) {
  61. var MARArray = [];
  62. var MARArrayString = GM_getValue("MARArrayString", null);
  63. if(MARArrayString) { MARArray = JSON.parse(MARArrayString); }
  64.  
  65. var unreadImg = '<svg style="vertical-align: middle;" width="15" height="15" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="book-open" class="svg-inline--fa fa-book-open fa-w-18" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M542.22 32.05c-54.8 3.11-163.72 14.43-230.96 55.59-4.64 2.84-7.27 7.89-7.27 13.17v363.87c0 11.55 12.63 18.85 23.28 13.49 69.18-34.82 169.23-44.32 218.7-46.92 16.89-.89 30.02-14.43 30.02-30.66V62.75c.01-17.71-15.35-31.74-33.77-30.7zM264.73 87.64C197.5 46.48 88.58 35.17 33.78 32.05 15.36 31.01 0 45.04 0 62.75V400.6c0 16.24 13.13 29.78 30.02 30.66 49.49 2.6 149.59 12.11 218.77 46.95 10.62 5.35 23.21-1.94 23.21-13.46V100.63c0-5.29-2.62-10.14-7.27-12.99z"></path></svg>';
  66. var readImg = '<svg style="vertical-align: middle;" width="15" height="15" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="book" class="svg-inline--fa fa-book fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M448 360V24c0-13.3-10.7-24-24-24H96C43 0 0 43 0 96v320c0 53 43 96 96 96h328c13.3 0 24-10.7 24-24v-16c0-7.5-3.5-14.3-8.9-18.7-4.2-15.4-4.2-59.3 0-74.7 5.4-4.3 8.9-11.1 8.9-18.6zM128 134c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm0 64c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm253.4 250H96c-17.7 0-32-14.3-32-32 0-17.6 14.4-32 32-32h285.4c-1.9 17.1-1.9 46.9 0 64z"></path></svg>';
  67. }
  68. }
  69. //========================================================//
  70.  
  71. //================== Adding stylesheets ==================//
  72. if(true) {
  73. if(remove_non_english) {
  74. addGlobalStyle(`
  75. .gallery:not([data-tags~='12227']) {
  76. display: none;
  77. }
  78. `);
  79. }
  80. else if(!remove_non_english && partially_fade_all_non_english) {
  81. addGlobalStyle(`
  82. .gallery:not([data-tags~='12227']) > .cover > img,
  83. .gallery:not([data-tags~='12227']) > .cover > .caption{
  84. opacity: ` + non_english_fade_opacity + `;
  85. }
  86. `);
  87. }
  88.  
  89. if(mark_as_read_system_enabled)
  90. {
  91. let MARArraySelector = "";
  92. for(let i = 0; i < MARArray.length; i++)
  93. MARArraySelector += `.cover[href="`+MARArray[i]+`"] > img, .cover[href="`+MARArray[i]+`"] > .caption, `;
  94. MARArraySelector = MARArraySelector.substr(0, MARArraySelector.length-2);
  95.  
  96. addGlobalStyle(`
  97. `+MARArraySelector+`
  98. {
  99. opacity: `+marked_as_read_fade_opacity+`;
  100. }
  101. `);
  102. }
  103.  
  104. //fixing too long cover images
  105. addGlobalStyle(`
  106. .gallery, .gallery > .cover {
  107. max-height: 360px;
  108. }
  109. .gallery > .cover {
  110. overflow: hidden;
  111. padding: 0 !important;
  112. }
  113. .gallery > .cover > img {
  114. position: relative;
  115. min-height: 100%;
  116. }
  117. `);
  118.  
  119. addGlobalStyle(`
  120. /*browsing comics*/
  121. .container.index-container {
  122. text-align: center;
  123. max-width: 100%;
  124. width: ` + browse_thumnail_container_width + `px;
  125. }
  126. .gallery > .cover > img {
  127. width: 100%;
  128. }
  129. .container.index-container > div.gallery {
  130. width: ` + browse_thumbnail_width + `px;
  131. }
  132.  
  133. /*view comic pages*/
  134. div.thumb-container {
  135. width: auto;
  136. }
  137. #thumbnail-container {
  138. text-align: center;
  139. max-width: 100%;
  140. width: ` + pages_thumnail_container_width + `px;
  141. }
  142. div.thumb-container img {
  143. width: ` + pages_thumbnail_width + `px;
  144. }
  145. `);
  146.  
  147. if(version_grouping_enabled)
  148. {
  149. addGlobalStyle(`
  150. .overlayFlag
  151. {
  152. position: absolute;
  153. display: inline-block;
  154. top: 3px;
  155. left: 3px;
  156. z-index: 3;
  157. width: 18px;
  158. height: 12px;
  159. }
  160. .numOfVersions {
  161. border-radius: 10px;
  162. padding: 5px 10px;
  163. position: absolute;
  164. background-color: rgba(0,0,0,.7);
  165. color: rgba(255,255,255,.8);
  166. top: 7.5px;
  167. left: 105px;
  168. font-size: 12px;
  169. font-weight: 900;
  170. opacity: 1;
  171. width: 40px;
  172. z-index: 2;
  173. display: none;
  174. }
  175. .findVersionButton {
  176. border-radius: 10px;
  177. padding: 5px 10px;
  178. position: absolute;
  179. background-color: rgba(0,0,0,.4);
  180. color: rgba(255,255,255,.8);
  181. bottom: 7.5px;
  182. left: 7.5px;
  183. font-size: 12px;
  184. font-weight: 900;
  185. opacity: 1;
  186. width: 125px;
  187. z-index: 2;
  188. cursor: pointer;
  189. }
  190. .versionNextButton {
  191. border-radius: 10px;
  192. padding: 5px 10px;
  193. position: absolute;
  194. background-color: rgba(0,0,0,.7);
  195. color: rgba(255,255,255,.8);
  196. top: 7.5px;
  197. right: 7.5px;
  198. font-size: 12px;
  199. font-weight: 900;
  200. opacity: 1;
  201. display: none;
  202. z-index: 2;
  203. cursor: pointer;
  204. }
  205. .versionPrevButton {
  206. border-radius: 10px;
  207. padding: 5px 10px;
  208. position: absolute;
  209. background-color: rgba(0,0,0,.7);
  210. color: rgba(255,255,255,.8);
  211. top: 7.5px;
  212. left: 7.5px;
  213. font-size: 12px;
  214. font-weight: 900;
  215. opacity: 1;
  216. z-index: 2;
  217. display: none;
  218. cursor: pointer;
  219. }
  220.  
  221. .findVersionButton:focus, .findVersionButton:hover, .findVersionButton:active,
  222. .versionNextButton:focus, .versionNextButton:hover, .versionNextButton:active,
  223. .versionPrevButton:focus, .versionPrevButton:hover, .versionPrevButton:active
  224. {
  225. background-color: rgba(50,50,50,1);
  226. }
  227. `);
  228. }
  229.  
  230. if(mark_as_read_system_enabled)
  231. {
  232. addGlobalStyle(`
  233. .readTag {
  234. border-radius: 10px;
  235. padding: 5px 10px;
  236. position: absolute;
  237. background-color: rgba(0,0,0,.7);
  238. color: rgba(255,255,255,.8);
  239. bottom: 7.5px;
  240. right: 7.5px;
  241. font-size: `+read_tag_font_size+`px;
  242. font-weight: 900;
  243. opacity: 1;
  244. }
  245.  
  246. #markAsRead, #markAsRead:visited {
  247. background-color: #3d9e48;
  248. }
  249. #markAsRead:active, #markAsRead:hover {
  250. background-color: #52bc5e;
  251. }
  252.  
  253. #markAsUnRead, #markAsUnRead:visited {
  254. background-color: rgb(218, 53, 53);
  255. }
  256. #markAsUnRead:active, #markAsUnRead:hover {
  257. background-color: #e26060;
  258. }
  259.  
  260. .gallery {
  261. position: relative;
  262. }
  263. `);
  264. }
  265.  
  266. if(subscription_system_enabled) {
  267. addGlobalStyle(`
  268. #tags .subbedTag, #tags .subbedTag:visited {
  269. background-color: #2c5030;
  270. }
  271. #tags .subbedTag:active, #tags .subbedTag:hover {
  272. background-color: #416144;
  273. }
  274.  
  275. #subTo, #subTo:visited {
  276. background-color: #3d9e48;
  277. }
  278. #subTo:active, #subTo:hover {
  279. background-color: #52bc5e;
  280. }
  281.  
  282. #unsubTo, #unsubTo:visited {
  283. background-color: rgb(218, 53, 53);
  284. }
  285. #unsubTo:active, #unsubTo:hover {
  286. background-color: #e26060;
  287. }
  288.  
  289. #sub-content ul {
  290. text-align: left;
  291. }
  292. #sub-content li {
  293. box-sizing: border-box;
  294. display: inline-block;
  295. width: 25%;
  296. text-align: center;
  297. padding: 5px 20px;
  298. }
  299.  
  300. #subTo, #unsubTo {
  301. height: auto;
  302. line-height: initial;
  303. cursor: pointer;
  304. font-size: 0.5em;
  305. padding: 6px 12px;
  306. }
  307. `);
  308. }
  309. }
  310. //========================================================//
  311.  
  312.  
  313. //================== On Comic info page ==================//
  314. if(window.location.href.match(/^.+?\/g\/.+?\/(\?.*|\#.*|)$/g)) //if on the comic info page
  315. {
  316. //=== Mark as read system ===//
  317. if(mark_as_read_system_enabled) {
  318. var item = window.location.href.split("nhentai.net")[1].split("?")[0].split("#")[0]; //get item from url
  319.  
  320. if(MARArray.includes(item)) //if item is marked as read
  321. $(".buttons").append('<a href="#" id="markAsUnRead" class="btn btn-secondary">'+unreadImg+' <span style="vertical-align: middle;">Mark as unread</span></a>'); //..add unmark button
  322. else
  323. $(".buttons").append('<a href="#" id="markAsRead" class="btn btn-secondary">'+readImg+' <span style="vertical-align: middle;">Mark as read</span></a>'); //...add mark button
  324.  
  325. AddMARClickListeners();
  326. }
  327. //===========================//
  328.  
  329. //==== Subscribe system =====//
  330. if(subscription_system_enabled) {
  331. let SubArraySelector = SubArray.join("'], .tag[href='");
  332. $(".tag[href='" + SubArraySelector + "']").addClass("subbedTag");
  333. }
  334. //===========================//
  335.  
  336. //=== HQ thumbnail system ===//
  337. if(load_high_quality_pages_thumbnails && $("#thumbnail-container").length !== 0) {
  338. $("#thumbnail-container > .thumb-container > .gallerythumb > img").one("load", function(){
  339. $(this).attr("src", $(this).attr("src").replace("//t.", "//i.").replace("t.jpg", ".jpg").replace("t.png", ".png"));
  340. });
  341. }
  342. //===========================//
  343. }
  344. //========================================================//
  345.  
  346. //============== On Artist/group info page ===============//
  347. else if(subscription_system_enabled && (window.location.href.match(/^.+?\/artist\/.+?\/(popular)?(\?.*?|\#.*?|)$/g) || window.location.href.match(/^.+?\/group\/.+?\/(popular)?(\?.*?|\#.*?|)$/g))) //in artist or group page
  348. {
  349. var subItem = window.location.href.split("nhentai.net")[1].split("popular")[0].split("?")[0].split("#")[0]; //get item from url
  350. if(SubArray.includes(subItem)) //if subscribed
  351. $("h1").append('<a href="#" id="unsubTo" class="btn btn-secondary"><span style="vertical-align: middle;">Unsubscribe</span></a>'); //...add unsub button
  352. else
  353. $("h1").append('<a href="#" id="subTo" class="btn btn-secondary"><span style="vertical-align: middle;">Subscribe</span></a>'); //...add sub button
  354.  
  355. AddSubClickListeners();
  356. }
  357. //========================================================//
  358.  
  359. //====================== Subs page =======================//
  360. else if(subscription_system_enabled && window.location.href.match(/^.+?\/subscriptions\/(\?.*|\#.*|)$/g)) //in subs page
  361. {
  362. $("head title").html('Subscriptions').prop("style", "font-size: 3.5em;");
  363. $("#content").prepend('<h1>Subscriptions</h1>');
  364. $("#content > .container").removeClass("error").addClass("artists-section").prop("id", "tag-container");
  365. $(".artists-section").before("<h2 style='font-size: 2em;'>Artists</h2>");
  366. $(".artists-section").after('<div class="container groups-section" id="tag-container"></div>');
  367. $(".groups-section").before("<h2 style='font-size: 2em; margin-top: 50px;'>Groups</h2>");
  368.  
  369. var artistsHTML = "";
  370. var groupsHTML = "";
  371. for(let i = 0; i < SubArray.length; i++) {
  372. if(SubArray[i].split("/")[1].split("/")[0] == "artist")
  373. artistsHTML += '<a class="tag" href="'+SubArray[i]+'">'+(SubArray[i].split("/")[2].split("/")[0].replace(/\-/g, " "))+'</a>';
  374. else
  375. groupsHTML += '<a class="tag" href="'+SubArray[i]+'">'+(SubArray[i].split("/")[2].split("/")[0].replace(/\-/g, " "))+'</a>';
  376. }
  377. $(".artists-section").html(artistsHTML);
  378. $(".groups-section").html(groupsHTML);
  379. }
  380. //========================================================//
  381.  
  382.  
  383. //====================== all pages with lists of comics ====================//
  384. if($(".container.index-container, #favcontainer.container").length !== 0)
  385. {
  386. //=== HQ thumbnail system ===//
  387. if(load_high_quality_browse_thumbnails) {
  388. $(".container.index-container > .gallery > .cover > img, #favcontainer.container > .gallery-favorite > .gallery > .cover > img").one("load", function(){
  389. $(this).attr("src", $(this).attr("src").replace("//t.", "//i.").replace("thumb.jpg", "1.jpg").replace("thumb.png", "1.png"));
  390. });
  391. }
  392. //===========================//
  393.  
  394. //=== Mark as read system ===//
  395. if(mark_as_read_system_enabled) {
  396. let MARArraySelector = MARArray.join("'], .cover[href='");
  397. $(".cover[href='" + MARArraySelector + "']").append("<div class='readTag'>READ</div>");
  398. }
  399. //===========================//
  400.  
  401. //=== Version Grouping system ===//
  402. if(version_grouping_enabled) {
  403. $(".cover").parent().append("<div class='findVersionButton'>Find Alt Versions</div>");
  404. $(".cover").parent().append("<div class='numOfVersions'>1/1</div>");
  405. $(".cover").parent().append("<div class='versionNextButton'>►</div>");
  406. $(".cover").parent().append("<div class='versionPrevButton'>◄</div>");
  407.  
  408. $(".findVersionButton").click(function(e){
  409. e.preventDefault();
  410. AddAltVersionsToThis($(this));
  411. });
  412.  
  413. if(auto_group_on_page_comics)
  414. GroupAltVersionsOnPage();
  415.  
  416. $(".versionPrevButton").click(function(e){
  417. e.preventDefault();
  418. let toHide = $(this).parent().find(".cover").filter(":visible");
  419. let toShow = toHide.prev();
  420. if(!toShow || toShow.length <= 0)
  421. return;
  422. if(!toShow.is(".cover"))
  423. toShow = toHide.prevUntil(".cover", ":last").prev();
  424. if(!toShow || toShow.length <= 0)
  425. return;
  426. toHide.hide(100);
  427. toShow.show(100);
  428. let n = $(this).parent().find(".numOfVersions");
  429. n.text( (Number(n.text().split("/")[0])-1) + "/" + n.text().split("/")[1] );
  430. });
  431. $(".versionNextButton").click(function(e){
  432. e.preventDefault();
  433. let toHide = $(this).parent().find(".cover").filter(":visible");
  434. let toShow = toHide.next();
  435. if(!toShow || toShow.length <= 0)
  436. return;
  437. if(!toShow.is(".cover"))
  438. toShow = toHide.nextUntil(".cover", ":last").next();
  439. if(!toShow || toShow.length <= 0)
  440. return;
  441. toHide.hide(100);
  442. toShow.show(100);
  443. let n = $(this).parent().find(".numOfVersions");
  444. n.text( (Number(n.text().split("/")[0])+1) + "/" + n.text().split("/")[1] );
  445. });
  446. }
  447. //===========================//
  448. }
  449. //==========================================================================//
  450.  
  451. //====================== Settings page ===================//
  452. else if($("#settings-container").length !== 0)
  453. {
  454. addGlobalStyle(`
  455. #settings-container .custom-settings {
  456. margin: 5px 5px 5px 20px;
  457. }
  458.  
  459. #settings-container .custom-settings input[type="text"],
  460. #settings-container .custom-settings input[type="number"]{
  461. width: 70px;
  462. height: 25px;
  463. border-radius: 3px;
  464. text-align: center;
  465. padding: 0;
  466. }
  467.  
  468. #settings-container .custom-settings.disabled-setting {
  469. color: RGBA(153, 153, 153, 1);
  470. opacity: 0.3;
  471. }
  472.  
  473. #settings-container h2 {position: relative;}
  474. #settings-container #settings-saved-mark {
  475. color: green;
  476. font-size: 15px;
  477. position: absolute;
  478. right: 0;
  479. top: 10px;
  480. display: none;
  481. }
  482.  
  483. #importexportdiv {
  484. position: fixed;
  485. top: 10%;
  486. left: 10%;
  487. width: 80%;
  488. height: 80%;
  489. background-color: #393939;
  490. padding: 3%;
  491. border-radius: 15px;
  492. }
  493. #importexportdiv > textarea {
  494. width: 100%;
  495. height: 90%;
  496. }
  497. `);
  498.  
  499. let settingsHTML = `<br><div id="customSettingsContainer"><form class="form-horizontal" role="form">
  500. <h2>NHentai Improved Settings <span id="settings-saved-mark">Saved 🗸</span></h2>
  501.  
  502. <h3>Non-English Settings</h3>
  503. <div class="custom-settings"><div class="form-control">
  504. <label><input id="remove_non_english" type="checkbox">
  505. Remove Non-English</label>
  506. </div></div>
  507.  
  508. <div class="custom-settings"><div class="form-control">
  509. <label><input id="partially_fade_all_non_english" type="checkbox">
  510. Partially Fade Non-English</label>
  511. </div></div>
  512.  
  513. <div class="custom-settings">
  514. <label>Non-English Fade Opacity
  515. <input id="non_english_fade_opacity" type="text" placeholder="0.0 - 1.0" autocomplete="off"></label>
  516. </div>
  517.  
  518.  
  519. <h3>Browse Section Settings</h3>
  520. <div class="custom-settings" title="height scales automatically">
  521. <label>Thumbnail Width
  522. <input id="browse_thumbnail_width" type="number" placeholder="250"> px</label>
  523. </div>
  524.  
  525. <div class="custom-settings" title="max-width = 100% of available space, meaning no need to worry about going too big">
  526. <label>Thumbnail Container Width
  527. <input id="browse_thumnail_container_width" type="number" placeholder="1350"> px</label>
  528. </div>
  529.  
  530. <div class="custom-settings"><div class="form-control">
  531. <label><input id="load_high_quality_browse_thumbnails" type="checkbox">
  532. HQ Thumbnails</label>
  533. </div></div>
  534.  
  535.  
  536. <h3>Comic Pages Section Settings</h3>
  537. <div class="custom-settings" title="height scales automatically">
  538. <label>Thumbnail Width
  539. <input id="pages_thumbnail_width" type="number" placeholder="250"> px</label>
  540. </div>
  541.  
  542. <div class="custom-settings" title="max-width = 100% of available space, meaning no need to worry about going too big">
  543. <label>Thumbnail Container Width
  544. <input id="pages_thumnail_container_width" type="number" placeholder="1350"> px</label>
  545. </div>
  546.  
  547. <div class="custom-settings"><div class="form-control">
  548. <label><input id="load_high_quality_pages_thumbnails" type="checkbox">
  549. HQ Thumbnails</label>
  550. </div></div>
  551.  
  552.  
  553. <h3>Mark As Read Settings</h3>
  554. <div class="custom-settings"><div class="form-control">
  555. <label><input id="mark_as_read_system_enabled" type="checkbox">
  556. Enabled</label>
  557. </div></div>
  558.  
  559. <div class="custom-settings">
  560. <label>Fade Opacity
  561. <input id="marked_as_read_fade_opacity" type="text" placeholder="0.0 - 1.0" autocomplete="off"></label>
  562. </div>
  563.  
  564. <div class="custom-settings">
  565. <label>Read Tag Font Size
  566. <input id="read_tag_font_size" type="number" placeholder="15"> px</label>
  567. </div>
  568.  
  569.  
  570. <h3>Subscription Settings</h3>
  571. <div class="custom-settings"><div class="form-control">
  572. <label><input id="subscription_system_enabled" type="checkbox">
  573. Enabled</label>
  574. </div></div>
  575.  
  576. <h3>Version Grouping Settings</h3>
  577. <div class="custom-settings"><div class="form-control">
  578. <label><input id="version_grouping_enabled" type="checkbox">
  579. Enabled</label>
  580. </div></div>
  581.  
  582. <div class="custom-settings"><div class="form-control">
  583. <label><input id="version_grouping_filter_brackets" type="checkbox">
  584. Filter out normal brackets for version searches<br><sup>(square brackets are always filtered out regardless of this setting)</sup></label>
  585. </div></div>
  586.  
  587. <div class="custom-settings"><div class="form-control">
  588. <label><input id="auto_group_on_page_comics" type="checkbox">
  589. Automatically group on-page comics<br><sup>(doesn't search the site, just current page)</sup></label>
  590. </div></div>
  591.  
  592. <br><br>
  593. </form>
  594. <div style="max-width: 800px; margin-left: auto; margin-right: auto;"><button id="importexportButt">Import/Export Subs and Marked as Read</button></div>
  595. <br><br>
  596. </div>`;
  597. $("#settings-container").append(settingsHTML);
  598. InitialValuesForSettings();
  599. $("#settings-container form:last").change(function(){
  600. UpdateSettingsValues();
  601. });
  602. $("#importexportButt").click(function(){
  603. if($("#importexportdiv").length == 0)
  604. {
  605. $("html").append(`<div id="importexportdiv"><textarea></textarea><br><br><button id="saveimportexport">Import</button><button id="backimportexport">Back</button></div>`);
  606.  
  607. $("#importexportdiv > textarea").val(SubArrayString + "|||||" + MARArrayString);
  608.  
  609. $("#saveimportexport").click(function(){
  610. if($("#importexportdiv > textarea").val().indexOf("|||||") < 0) {
  611. alert("invalid data");
  612. return;
  613. }
  614. SubArrayString = $("#importexportdiv > textarea").val().split("|||||")[0];
  615. MARArrayString = $("#importexportdiv > textarea").val().split("|||||")[1];
  616.  
  617. GM_setValue("SubArrayString", SubArrayString);
  618. GM_setValue("MARArrayString", MARArrayString);
  619. alert("Done!");
  620. location.reload();
  621. });
  622. $("#backimportexport").click(function(){
  623. $("#importexportdiv").remove();
  624. });
  625. }
  626. });
  627. }
  628. //========================================================//
  629.  
  630. //====================== All pages =======================//
  631. if(subscription_system_enabled) {
  632. $(".menu.right").prepend('<li><a href="/subscriptions/"><i class="fa fa-heartbeat"></i> Subscriptions</a></li>');
  633. }
  634. //========================================================//
  635.  
  636. function GroupAltVersionsOnPage()
  637. {
  638. let i = 0;
  639. let found = $(".container > .gallery");
  640. while(!!found && i < found.length)
  641. {
  642. AddAltVersionsToThisFromPage(found[i]);
  643. i++;
  644. found = $(".container > .gallery");
  645. }
  646. }
  647.  
  648. function AddAltVersionsToThisFromPage(target)
  649. {
  650. let place = $(target);
  651. place.addClass("ignoreThis");
  652. let title = place.find(".cover > .caption").text();
  653. if(!title || title.length <= 0)
  654. return;
  655. let found = $(".container > .gallery:not(.ignoreThis)");
  656. let numOfValid = 0;
  657. for(let i = 0; i < found.length; i++) //loop through galleries
  658. {
  659. let cap = $(found[i]).find(".caption");
  660. if(cap.length == 1) //if the gallery includes just one item
  661. {
  662. if(IncludesAll(cap.text(), title)) //valid target
  663. {
  664. if(partially_fade_all_non_english)
  665. $(found[i]).find(".cover > img, .cover > .caption").css("opacity", non_english_fade_opacity);
  666.  
  667. if($(found[i]).attr("data-tags").includes("12227")) //en
  668. {
  669. $(found[i]).find(".caption").append(`<img class="overlayFlag" src="`+flagEn+`">`);
  670. $(found[i]).find(".cover > img, .cover > .caption").css("opacity", "1");
  671. }
  672. else
  673. {
  674. if($(found[i]).attr("data-tags").includes("6346")) //jp
  675. $(found[i]).find(".caption").append(`<img class="overlayFlag" src="`+flagJp+`">`);
  676. else if($(found[i]).attr("data-tags").includes("29963")) //ch
  677. $(found[i]).find(".caption").append(`<img class="overlayFlag" src="`+flagCh+`">`);
  678.  
  679. if(!partially_fade_all_non_english)
  680. $(found[i]).find(".cover > img, .cover > .caption").css("opacity", "1");
  681. }
  682.  
  683. if(mark_as_read_system_enabled) {
  684. let MARArraySelector = MARArray.join("'], .cover[href='");
  685. $(found[i]).find(".cover[href='" + MARArraySelector + "']").append("<div class='readTag'>READ</div>");
  686. let readTag = $(found[i]).find(".readTag");
  687. if(!!readTag && readTag.length > 0)
  688. readTag.parent().parent().find(".cover > img, .cover > .caption").css("opacity", marked_as_read_fade_opacity);
  689. }
  690.  
  691. place.append($(found[i]).find(".cover"));
  692. $(found[i]).addClass("deleteThis");
  693. numOfValid++;
  694. }
  695. }
  696. else //the gallery incvludes multiple items
  697. {
  698. let addThese = false;
  699. for(let j = 0; j < cap.length; j++) //loop through items in the gallery
  700. {
  701. if(IncludesAll($(cap[j]).text(), title))
  702. {
  703. addThese = true; //if any of them match
  704. break;
  705. }
  706. }
  707.  
  708. if(addThese) //if any matched
  709. {
  710. for(let j = 0; j < cap.length; j++)
  711. place.append($(cap[j]).parent()); //add all
  712. $(found[i]).addClass("deleteThis");
  713. numOfValid += cap.length;
  714. }
  715. }
  716. }
  717. numOfValid++;
  718. place.removeClass("deleteThis");
  719. place.removeClass("ignoreThis");
  720. $(".deleteThis").remove();
  721. if(numOfValid > 1)
  722. {
  723. place.find(".cover:not(:first)").css("display", "none");
  724. place.find(".versionPrevButton, .versionNextButton, .numOfVersions").show(200);
  725. place.find(".numOfVersions").text("1/" + numOfValid);
  726. //place.find(".findVersionButton").hide();
  727. }
  728. }
  729.  
  730. function IncludesAll(string, search)
  731. {
  732. string = CleanupSearchString(string);
  733. search = CleanupSearchString(search);
  734. let yes = true;
  735. let searches = search.split(" ");
  736. console.log(string + " ::: includes all::: " + searches);
  737. for(let i = 0; i < searches.length; i++)
  738. if(!!searches[i] && searches[i].length > 0 && !string.includes(searches[i]))
  739. yes = false;
  740. console.log("Chuu,ni, - " + yes);
  741. return yes;
  742. }
  743.  
  744. function AddAltVersionsToThis(target)
  745. {
  746. let place = target;
  747. let title = place.parent().find(".cover:visible > .caption").text();
  748. $.get(BuildUrl(title), function(data){
  749. let found = $(data).find(".container > .gallery");
  750. if(!found || found.length <= 0)
  751. {
  752. alert("error reading data");
  753. return;
  754. }
  755. place.parent().find(".cover").remove();
  756. try
  757. {
  758. for(let i = 0; i < found.length; i++)
  759. {
  760. if(partially_fade_all_non_english)
  761. $(found[i]).find(".cover > img, .cover > .caption").css("opacity", non_english_fade_opacity);
  762.  
  763. if($(found[i]).attr("data-tags").includes("12227")) //en
  764. {
  765. $(found[i]).find(".caption").append(`<img class="overlayFlag" src="`+flagEn+`">`);
  766. $(found[i]).find(".cover > img, .cover > .caption").css("opacity", "1");
  767. }
  768. else
  769. {
  770. if($(found[i]).attr("data-tags").includes("6346")) //jp
  771. $(found[i]).find(".caption").append(`<img class="overlayFlag" src="`+flagJp+`">`);
  772. else if($(found[i]).attr("data-tags").includes("29963")) //ch
  773. $(found[i]).find(".caption").append(`<img class="overlayFlag" src="`+flagCh+`">`);
  774.  
  775. if(!partially_fade_all_non_english)
  776. $(found[i]).find(".cover > img, .cover > .caption").css("opacity", "1");
  777. }
  778.  
  779. if(mark_as_read_system_enabled) {
  780. let MARArraySelector = MARArray.join("'], .cover[href='");
  781. $(found[i]).find(".cover[href='" + MARArraySelector + "']").append("<div class='readTag'>READ</div>");
  782. let readTag = $(found[i]).find(".readTag");
  783. if(!!readTag && readTag.length > 0)
  784. readTag.parent().parent().find(".cover > img, .cover > .caption").css("opacity", marked_as_read_fade_opacity);
  785. }
  786.  
  787. let thumbnailReplacement;
  788. if(!!$(found[i]).find(".cover > img").attr("data-src"))
  789. thumbnailReplacement = $(found[i]).find(".cover > img").attr("data-src").replace("//t.", "//i.").replace("thumb.jpg", "1.jpg").replace("thumb.png", "1.png");
  790. else
  791. thumbnailReplacement = $(found[i]).find(".cover > img").attr("src").replace("//t.", "//i.").replace("thumb.jpg", "1.jpg").replace("thumb.png", "1.png");
  792.  
  793. $(found[i]).find(".cover > img").attr("src", thumbnailReplacement);
  794. place.parent().append($(found[i]).find(".cover"));
  795. }
  796. }
  797. catch(er)
  798. {
  799. alert("error modifying data: " + er);
  800. return;
  801. }
  802. place.parent().find(".cover:not(:first)").css("display", "none");
  803. place.parent().find(".versionPrevButton, .versionNextButton, .numOfVersions").show(200);
  804. place.parent().find(".numOfVersions").text("1/" + (found.length));
  805. place.hide(200);
  806. }).fail(function(e){
  807. alert("error getting data: " + e);
  808. });
  809. }
  810.  
  811. function CleanupSearchString(title)
  812. {
  813. title = title.replace(/\[.*?\]/g, "");
  814. if(version_grouping_filter_brackets)
  815. title = title.replace(/\(.*?\)/g, "");
  816. return title;
  817. }
  818.  
  819. function BuildUrl(title)
  820. {
  821. let url = CleanupSearchString(title);
  822. url = url.replace(/\s+?-/g, " ");
  823. url = url.replace(/,/g, " ");
  824. url = encodeURI(url);
  825. url = "https://nhentai.net/search/?q=" + url;
  826. return url;
  827. }
  828.  
  829. function InitialValuesForSettings() {
  830. $("#remove_non_english").prop("checked", remove_non_english);
  831. $("#partially_fade_all_non_english").prop("checked", partially_fade_all_non_english);
  832. $("#non_english_fade_opacity").val(non_english_fade_opacity);
  833. $("#browse_thumbnail_width").val(browse_thumbnail_width);
  834. $("#browse_thumnail_container_width").val(browse_thumnail_container_width);
  835. $("#load_high_quality_browse_thumbnails").prop("checked", load_high_quality_browse_thumbnails);
  836. $("#pages_thumbnail_width").val(pages_thumbnail_width);
  837. $("#pages_thumnail_container_width").val(pages_thumnail_container_width);
  838. $("#load_high_quality_pages_thumbnails").prop("checked", load_high_quality_pages_thumbnails);
  839. $("#mark_as_read_system_enabled").prop("checked", mark_as_read_system_enabled);
  840. $("#marked_as_read_fade_opacity").val(marked_as_read_fade_opacity);
  841. $("#read_tag_font_size").val(read_tag_font_size);
  842. $("#subscription_system_enabled").prop("checked", subscription_system_enabled);
  843. $("#version_grouping_enabled").prop("checked", version_grouping_enabled);
  844. $("#version_grouping_filter_brackets").prop("checked", version_grouping_filter_brackets);
  845. $("#auto_group_on_page_comics").prop("checked", auto_group_on_page_comics);
  846. }
  847.  
  848. function UpdateSettingsValues() {
  849. remove_non_english = $("#remove_non_english").is(':checked');
  850. partially_fade_all_non_english = $("#partially_fade_all_non_english").is(':checked');
  851. non_english_fade_opacity = $("#non_english_fade_opacity").val();
  852. browse_thumbnail_width = $("#browse_thumbnail_width").val();
  853. browse_thumnail_container_width = $("#browse_thumnail_container_width").val();
  854. load_high_quality_browse_thumbnails = $("#load_high_quality_browse_thumbnails").is(':checked');
  855. pages_thumbnail_width = $("#pages_thumbnail_width").val();
  856. pages_thumnail_container_width = $("#pages_thumnail_container_width").val();
  857. load_high_quality_pages_thumbnails = $("#load_high_quality_pages_thumbnails").is(':checked');
  858. mark_as_read_system_enabled = $("#mark_as_read_system_enabled").is(':checked');
  859. marked_as_read_fade_opacity = $("#marked_as_read_fade_opacity").val();
  860. read_tag_font_size = $("#read_tag_font_size").val();
  861. subscription_system_enabled = $("#subscription_system_enabled").is(':checked');
  862. version_grouping_enabled = $("#version_grouping_enabled").is(':checked');
  863. version_grouping_filter_brackets = $("#version_grouping_filter_brackets").is(':checked');
  864. auto_group_on_page_comics = $("#auto_group_on_page_comics").is(':checked');
  865.  
  866. GM_setValue("remove_non_english", remove_non_english);
  867. GM_setValue("partially_fade_all_non_english", partially_fade_all_non_english);
  868. GM_setValue("non_english_fade_opacity", non_english_fade_opacity);
  869. GM_setValue("browse_thumbnail_width", browse_thumbnail_width);
  870. GM_setValue("browse_thumnail_container_width", browse_thumnail_container_width);
  871. GM_setValue("load_high_quality_browse_thumbnails", load_high_quality_browse_thumbnails);
  872. GM_setValue("pages_thumbnail_width", pages_thumbnail_width);
  873. GM_setValue("pages_thumnail_container_width", pages_thumnail_container_width);
  874. GM_setValue("load_high_quality_pages_thumbnails", load_high_quality_pages_thumbnails);
  875. GM_setValue("mark_as_read_system_enabled", mark_as_read_system_enabled);
  876. GM_setValue("marked_as_read_fade_opacity", marked_as_read_fade_opacity);
  877. GM_setValue("read_tag_font_size", read_tag_font_size);
  878. GM_setValue("subscription_system_enabled", subscription_system_enabled);
  879. GM_setValue("version_grouping_enabled", version_grouping_enabled);
  880. GM_setValue("version_grouping_filter_brackets", version_grouping_filter_brackets);
  881. GM_setValue("auto_group_on_page_comics", auto_group_on_page_comics);
  882.  
  883. $("#settings-saved-mark").fadeIn(500, function() {
  884. setTimeout(function() {
  885. $("#settings-saved-mark").fadeOut(500);
  886. }, 1000);
  887. });
  888.  
  889. if(remove_non_english) {
  890. $("#partially_fade_all_non_english").prop("disabled", true);
  891. $("#non_english_fade_opacity").prop("disabled", true);
  892. $("#partially_fade_all_non_english").parentsUntil(".custom-settings").parent().addClass("disabled-setting");
  893. $("#non_english_fade_opacity").parentsUntil(".custom-settings").parent().addClass("disabled-setting");
  894. }
  895. else {
  896. $("#partially_fade_all_non_english").prop("disabled", false);
  897. $("#non_english_fade_opacity").prop("disabled", false);
  898. $("#partially_fade_all_non_english").parentsUntil(".custom-settings").parent().removeClass("disabled-setting");
  899. $("#non_english_fade_opacity").parentsUntil(".custom-settings").parent().removeClass("disabled-setting");
  900.  
  901. if(!partially_fade_all_non_english) {
  902. $("#non_english_fade_opacity").prop("disabled", true);
  903. $("#non_english_fade_opacity").parentsUntil(".custom-settings").parent().addClass("disabled-setting");
  904. }
  905. else {
  906. $("#non_english_fade_opacity").prop("disabled", false);
  907. $("#non_english_fade_opacity").parentsUntil(".custom-settings").parent().removeClass("disabled-setting");
  908. }
  909. }
  910.  
  911. if(mark_as_read_system_enabled) {
  912. $("#marked_as_read_fade_opacity, #read_tag_font_size").prop("disabled", false);
  913. $("#marked_as_read_fade_opacity, #read_tag_font_size").parentsUntil(".custom-settings").parent().removeClass("disabled-setting");
  914. }
  915. else {
  916. $("#marked_as_read_fade_opacity, #read_tag_font_size").prop("disabled", true);
  917. $("#marked_as_read_fade_opacity, #read_tag_font_size").parentsUntil(".custom-settings").parent().addClass("disabled-setting");
  918. }
  919. }
  920.  
  921. function AddSubClickListeners() {
  922. $("#subTo").click(function(){
  923.  
  924. //get the array again to make sure we have an up to date array (since other tabs could have modified it since loading this page)
  925. SubArrayString = GM_getValue("SubArrayString", null);
  926. if(SubArrayString) { SubArray = JSON.parse(SubArrayString); }
  927.  
  928. SubArray.push(subItem); //add to array
  929. SubArrayString = JSON.stringify(SubArray); //convert array to string
  930. GM_setValue("SubArrayString", SubArrayString); //save string
  931. $(this).html('<span style="vertical-align: middle;">Unsubscribe</span>').prop("id", "unsubTo");
  932. $(this).off();
  933. AddSubClickListeners();
  934. });
  935. $("#unsubTo").click(function(){
  936.  
  937. //get the array again to make sure we have an up to date array (since other tabs could have modified it since loading this page)
  938. SubArrayString = GM_getValue("SubArrayString", null);
  939. if(SubArrayString) { SubArray = JSON.parse(SubArrayString); }
  940.  
  941. //do it mutiple times if needed (due to multiple tab fuckery)
  942. while(SubArray.indexOf(subItem) >= 0)
  943. SubArray.splice(SubArray.indexOf(subItem), 1); //remove from array
  944.  
  945. SubArrayString = JSON.stringify(SubArray); //convert array to string
  946. GM_setValue("SubArrayString", SubArrayString); //save string
  947. $(this).html('<span style="vertical-align: middle;">Subscribe</span>').prop("id", "subTo");
  948. $(this).off();
  949. AddSubClickListeners();
  950. });
  951. }
  952.  
  953. function AddMARClickListeners() {
  954. $("#markAsRead").click(function(){
  955.  
  956. //get the array again to make sure we have an up to date array (since other tabs could have modified it since loading this page)
  957. MARArrayString = GM_getValue("MARArrayString", null);
  958. if(MARArrayString) { MARArray = JSON.parse(MARArrayString); }
  959.  
  960. MARArray.push(item); //add to array
  961. MARArrayString = JSON.stringify(MARArray); //covert array to string
  962. GM_setValue("MARArrayString", MARArrayString); //save string
  963. $(this).html(unreadImg+' <span style="vertical-align: middle;">Mark as unread</span>').prop("id", "markAsUnRead");
  964. $(this).off();
  965. AddMARClickListeners();
  966. });
  967.  
  968. $("#markAsUnRead").click(function(){
  969.  
  970. //get the array again to make sure we have an up to date array (since other tabs could have modified it since loading this page)
  971. MARArrayString = GM_getValue("MARArrayString", null);
  972. if(MARArrayString) { MARArray = JSON.parse(MARArrayString); }
  973.  
  974. //do it mutiple times if needed (due to multiple tab fuckery)
  975. while(MARArray.indexOf(item) >= 0)
  976. MARArray.splice(MARArray.indexOf(item), 1); //remove from array
  977.  
  978. MARArrayString = JSON.stringify(MARArray); //covert array to string
  979. GM_setValue("MARArrayString", MARArrayString); //save string
  980. $(this).html(readImg+' <span style="vertical-align: middle;">Mark as read</span>').prop("id", "markAsRead");
  981. $(this).off();
  982. AddMARClickListeners();
  983. });
  984. }
  985.  
  986. function addGlobalStyle(css) {
  987. var head, style;
  988. head = document.getElementsByTagName('head')[0];
  989. if (!head) { return; }
  990. style = document.createElement('style');
  991. style.type = 'text/css';
  992. style.innerHTML = css;
  993. head.appendChild(style);
  994. }
  995. })();