Hitomi - Search & UI Tweaks

Various search filters and user experience enhancers

04.09.2023 itibariyledir. En son verisyonu görün.

  1. // ==UserScript==
  2. // @name Hitomi - Search & UI Tweaks
  3. // @namespace brazenvoid
  4. // @version 6.0.1
  5. // @author brazenvoid
  6. // @license GPL-3.0-only
  7. // @description Various search filters and user experience enhancers
  8. // @match https://hitomi.la/*
  9. // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js
  10. // @require https://greasyfork.org/scripts/375557-base-brazen-resource/code/Base%20Brazen%20Resource.js?version=1244990
  11. // @require https://greasyfork.org/scripts/416104-brazen-ui-generator/code/Brazen%20UI%20Generator.js?version=1245364
  12. // @require https://greasyfork.org/scripts/418665-brazen-configuration-manager/code/Brazen%20Configuration%20Manager.js?version=1245040
  13. // @require https://greasyfork.org/scripts/429587-brazen-item-attributes-resolver/code/Brazen%20Item%20Attributes%20Resolver.js?version=1244644
  14. // @require https://greasyfork.org/scripts/416105-brazen-base-search-enhancer/code/Brazen%20Base%20Search%20Enhancer.js?version=1245401
  15. // @grant GM_addStyle
  16. // @run-at document-end
  17. // ==/UserScript==
  18.  
  19. GM_addStyle(`#settings-wrapper{min-width:450px;width:450px}.disliked-tag{background-color:lightcoral !important}.disliked-tag:hover{background-color:indianred !important}.disliked-tag.favourite-tag{background-color:orange !important}.disliked-tag.favourite-tag:hover{background-color:darkorange !important}.favourite-tag{background-color:mediumseagreen !important}.favourite-tag:hover{background-color:forestgreen !important}`)
  20.  
  21. const IS_GALLERY_PAGE = $('#dl-button').length
  22.  
  23. const FILTER_GALLERY_TYPES = 'Show Gallery Types'
  24. const FILTER_PAGES = 'Pages'
  25. const FILTER_LANGUAGES = 'Languages'
  26.  
  27. const OPTION_REMOVE_RELATED_GALLERIES = 'Remove Related Galleries'
  28.  
  29. const UI_FAVOURITE_TAGS = 'Favourite Tags'
  30. const UI_DISLIKED_TAGS = 'Disliked Tags'
  31. const UI_SHOW_ALL_TAGS = 'Show All Gallery Tags'
  32.  
  33. class HitomiSearchAndUITweaks extends BrazenBaseSearchEnhancer
  34. {
  35. constructor()
  36. {
  37. super({
  38. isUserLoggedIn: false,
  39. itemDeepAnalysisSelector: '',
  40. itemLinkSelector: '',
  41. itemListSelectors: '.gallery-content',
  42. itemNameSelector: 'h1.lillie a',
  43. itemSelectors: '.acg,.anime,.cg,.dj,.manga',
  44. requestDelay: 0,
  45. scriptPrefix: 'hitomi-sui-',
  46. tagSelectorGenerator: (tag) => {
  47. let selector
  48. tag = encodeURIComponent(tag.trim())
  49. if (tag.startsWith('artist%3A')) {
  50. selector = 'a[href="/artist/' + tag.replace('artist%3A', '') + '-all.html"]'
  51. } else if (tag.startsWith('series%3A')) {
  52. selector = 'a[href="/series/' + tag.replace('series%3A', '') + '-all.html"]'
  53. } else {
  54. selector = 'a[href="/tag/' + tag + '-all.html"]'
  55. }
  56. return selector
  57. }
  58. })
  59. this._setupFeatures()
  60. this._setupUI()
  61. this._setupEvents()
  62. }
  63. /**
  64. * @private
  65. */
  66. _setupEvents()
  67. {
  68. if (IS_GALLERY_PAGE) {
  69. this._onBeforeUIBuild.push(() => this._performComplexOperation(
  70. FILTER_PAGES,
  71. (range) => !this._getConfig(OPTION_DISABLE_COMPLIANCE_VALIDATION) && this._configurationManager.generateValidationCallback(FILTER_PAGES)(range),
  72. (range) => {
  73. let navPages = $('.simplePagerNav li').length
  74. let pageCount = navPages > 0 ? navPages * 50 : $('.simplePagerPage1').length
  75. if (!Validator.isInRange(pageCount, range.minimum, range.maximum)) {
  76. top.close()
  77. }
  78. })
  79. )
  80. this._onBeforeUIBuild.push(() => this._performOperation(
  81. OPTION_REMOVE_RELATED_GALLERIES, () => $('.gallery-content').remove()))
  82. }
  83. this._onAfterUIBuild.push(() => this._uiGen.getSelectedSection()[0].userScript = this)
  84. this._onFirstHitAfterCompliance.push((item) => {
  85. this._performComplexOperation(UI_SHOW_ALL_TAGS, (flag) => flag && !IS_GALLERY_PAGE, () => {
  86. let tags = item.find('.relatedtags > ul > li')
  87. let lastTag = tags.last()
  88. if (lastTag.text() === '...') {
  89. lastTag.remove()
  90. tags.filter('.hidden-list-item').removeClass('hidden-list-item')
  91. }
  92. })
  93. })
  94. }
  95. /**
  96. * @private
  97. */
  98. _setupFeatures()
  99. {
  100. this._configurationManager
  101. .addCheckboxesGroup(FILTER_GALLERY_TYPES, [
  102. ['Anime', 'anime'],
  103. ['Artist CG', 'acg'],
  104. ['Doujinshi', 'dj'],
  105. ['Game CG', 'cg'],
  106. ['Manga', 'manga'],
  107. ], 'Show only selected gallery types.')
  108. .addCheckboxesGroup(FILTER_LANGUAGES, [
  109. ['N/A', 'not-applicable'],
  110. ['Japanese', 'japanese'],
  111. ['Chinese', 'chinese'],
  112. ['English', 'english'],
  113. ['Albanian', 'albanian'],
  114. ['Arabic', 'arabic'],
  115. ['Bulgarian', 'bulgarian'],
  116. ['Catalan', 'catalan'],
  117. ['Cebuano', 'cebuano'],
  118. ['Czech', 'czech'],
  119. ['Danish', 'danish'],
  120. ['Dutch', 'dutch'],
  121. ['Esperanto', 'esperanto'],
  122. ['Estonian', 'estonian'],
  123. ['Finnish', 'finnish'],
  124. ['French', 'french'],
  125. ['German', 'german'],
  126. ['Greek', 'greek'],
  127. ['Hebrew', 'hebrew'],
  128. ['Hungarian', 'hungarian'],
  129. ['Indonesian', 'indonesian'],
  130. ['Italian', 'italian'],
  131. ['Korean', 'korean'],
  132. ['Latin', 'latin'],
  133. ['Mongolian', 'mongolian'],
  134. ['Norwegian', 'norwegian'],
  135. ['Persian', 'persian'],
  136. ['Polish', 'polish'],
  137. ['Portuguese', 'portuguese'],
  138. ['Romanian', 'romanian'],
  139. ['Russian', 'russian'],
  140. ['Slovak', 'slovak'],
  141. ['Spanish', 'spanish'],
  142. ['Swedish', 'swedish'],
  143. ['Tagalog', 'tagalog'],
  144. ['Thai', 'thai'],
  145. ['Turkish', 'turkish'],
  146. ['Ukrainian', 'ukrainian'],
  147. ['Unspecified', 'unspecified'],
  148. ['Vietnamese', 'vietnamese'],
  149. ], 'Select languages to show')
  150. .addFlagField(OPTION_REMOVE_RELATED_GALLERIES, 'Remove related galleries section from gallery pages.')
  151. .addFlagField(UI_SHOW_ALL_TAGS, 'Show all gallery tags in search results.')
  152. .addRangeField(FILTER_PAGES, 0, Infinity, 'Close gallery pages that don\'t satisfy these page limits. Only works on galleries opened in new tabs.')
  153. this._addItemComplianceFilter(FILTER_LANGUAGES, (item, valueKeys) => {
  154. let languageLink = item.find('tr:nth-child(3) > td:nth-child(2) a')
  155. if (languageLink.length) {
  156. languageLink = languageLink.attr('href')
  157. for (let key of valueKeys) {
  158. if (languageLink.includes(key)) {
  159. return true
  160. }
  161. }
  162. return false
  163. }
  164. return valueKeys.includes('not-applicable')
  165. })
  166. this._addItemComplianceFilter(FILTER_GALLERY_TYPES, (item, valueKeys) => {
  167. for (let galleryClass of valueKeys) {
  168. if (item.hasClass(galleryClass)) {
  169. return true
  170. }
  171. }
  172. return false
  173. })
  174. let otherTagSections = IS_GALLERY_PAGE ? $('.tags') : null
  175. this._addItemTagHighlights(UI_FAVOURITE_TAGS, otherTagSections, 'favourite-tag', 'Specify favourite tags to highlight. "&" "|" can be used.')
  176. this._addItemTagHighlights(UI_DISLIKED_TAGS, otherTagSections, 'disliked-tag', 'Specify disliked tags to highlight. "&" "|" can be used.')
  177. this._addItemTagBlacklistFilter(10)
  178. }
  179. /**
  180. * @private
  181. */
  182. _setupUI()
  183. {
  184. this._userInterface = [
  185. this._uiGen.createTabsSection(['Filters', 'Blacklist', 'Highlights', 'Languages', 'Global', 'Stats'], [
  186. this._uiGen.createTabPanel('Filters', true).append([
  187. this._configurationManager.createElement(FILTER_GALLERY_TYPES),
  188. this._uiGen.createSeparator(),
  189. this._configurationManager.createElement(FILTER_PAGES),
  190. ]),
  191. this._uiGen.createTabPanel('Blacklist').append([
  192. this._configurationManager.createElement(OPTION_ENABLE_BLACKLIST),
  193. this._configurationManager.createElement(FILTER_TAG_BLACKLIST),
  194. ]),
  195. this._uiGen.createTabPanel('Highlights').append([
  196. this._configurationManager.createElement(UI_FAVOURITE_TAGS),
  197. this._configurationManager.createElement(UI_DISLIKED_TAGS),
  198. ]),
  199. this._uiGen.createTabPanel('Languages').append([
  200. this._configurationManager.createElement(FILTER_LANGUAGES),
  201. ]),
  202. this._uiGen.createTabPanel('Global').append([
  203. this._configurationManager.createElement(UI_SHOW_ALL_TAGS),
  204. this._configurationManager.createElement(OPTION_ALWAYS_SHOW_SETTINGS_PANE),
  205. this._uiGen.createSeparator(),
  206. this._createSettingsBackupRestoreFormActions(),
  207. ]),
  208. this._uiGen.createTabPanel('Stats').append([
  209. this._uiGen.createStatisticsFormGroup(FILTER_GALLERY_TYPES),
  210. this._uiGen.createStatisticsFormGroup(FILTER_LANGUAGES),
  211. this._uiGen.createStatisticsFormGroup(FILTER_TAG_BLACKLIST),
  212. this._uiGen.createSeparator(),
  213. this._uiGen.createStatisticsTotalsGroup(),
  214. ]),
  215. ]),
  216. this._configurationManager.createElement(OPTION_DISABLE_COMPLIANCE_VALIDATION),
  217. this._uiGen.createSeparator(),
  218. this._createSettingsFormActions(),
  219. this._uiGen.createSeparator(),
  220. this._uiGen.createStatusSection(),
  221. ]
  222. }
  223. }
  224.  
  225. (new HitomiSearchAndUITweaks).init()