Hanime Resumer and Hider

Store video timespamps locally, hide videos that have a timespamp, button to hide all videos in a playlist (all your liked videos)

  1. // ==UserScript==
  2. // @name Hanime Resumer and Hider
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.1
  5. // @description Store video timespamps locally, hide videos that have a timespamp, button to hide all videos in a playlist (all your liked videos)
  6. // @author You
  7. // @match https://player.hanime.tv/*
  8. // @match https://hanime.tv/*
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=hanime.tv
  10. // @grant GM.setValue
  11. // @grant GM.getValue
  12. // ==/UserScript==
  13.  
  14. function l(...args){
  15. console.log('[Resumer]', ...args)
  16. }
  17.  
  18. function key(){
  19. let key = document.URL.split(',')[2]
  20. return key
  21. }
  22.  
  23. if(document.URL.includes('player.hanime')){
  24. //Resumer
  25. let once = false
  26. //Observe changes to the DOM
  27. const observer = new MutationObserver(async (mutationsList, observer) => {
  28. if(!once){
  29. //Get video element
  30. let video = document.querySelector('video')
  31. if(video){
  32. //Resume
  33. let previousTime = await GM.getValue(key())
  34. if(previousTime){
  35. video.currentTime = previousTime
  36. l(`resuming ${key()} ${video.currentTime}`)
  37. }
  38. //Save currentTime
  39. video.ontimeupdate = () => {
  40. GM.setValue(key(), video.currentTime)
  41. }
  42. once = true
  43. }
  44. }
  45. })
  46. observer.observe(document, {subtree:true, childList:true, attributes:true})
  47. }else{
  48. async function hide(a){
  49. let name = a.href.replace('https://hanime.tv/videos/hentai/', '')
  50. name = name.split('?')[0] //to remove ?playlist
  51. let previousTime = await GM.getValue(name)
  52. if(previousTime !== undefined){
  53. l(name, previousTime)
  54. a.style.filter = 'brightness(0.1)'
  55. }
  56. }
  57. //Hider
  58. const observer = new MutationObserver((mutationsList, observer) => {
  59. for(let mutation of mutationsList){
  60. //home page
  61. if(mutation.target.className == 'lazy hvc__media__cover' && mutation.removedNodes.length == 0){
  62. hide(mutation.target.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement)
  63. }else if(mutation.target.className == 'lazy relative hvc2__lazy' && mutation.removedNodes.length == 0){
  64. hide(mutation.target.parentElement.parentElement)
  65. }else if(mutation.target.id == 'related_content' && mutation.removedNodes.length == 0){ //video page
  66. for(let a of mutation.target.querySelectorAll('.video__item a')){
  67. hide(a)
  68. }
  69. break
  70. }
  71. }
  72. //playlists (inefficient)
  73. if(document.URL.includes('/playlists/')){
  74. for(let a of document.querySelectorAll('.video__item a')){
  75. hide(a)
  76. }
  77.  
  78. //Hide all liked videos
  79. if(!document.querySelector('#hide-all')){
  80. let group = document.querySelector('.btn-toggle.btn-toggle--selected')
  81. group.insertAdjacentHTML('afterEnd', '<button id="hide-all" type="button" class="btn btn--active btn--flat" style="position: relative;"><div class="btn__content">Hide All</div></button>')
  82. document.querySelector('#hide-all').onclick = async () => {
  83. for(let a of document.querySelectorAll('.video__item a')){
  84. let name = a.href.replace('https://hanime.tv/videos/hentai/', '')
  85. name = name.split('?')[0] //to remove ?playlist
  86. let previousTime = await GM.getValue(name)
  87. if(previousTime === undefined){
  88. l('hiding', name)
  89. a.style.filter = 'brightness(0.1)'
  90. GM.setValue(name, 0)
  91. }
  92. }
  93. }
  94. }
  95. }
  96.  
  97. })
  98. observer.observe(document, {subtree:true, childList:true})
  99. }