@@ -703,6 +703,114 @@ extension.features.trackWatchedVideos = function () {
703703 }
704704} ;
705705
706+ /*--------------------------------------------------------------
707+ # HIDE WATCHED VIDEOS
708+ --------------------------------------------------------------*/
709+
710+ extension . features . hideWatchedVideos = function ( anything ) {
711+ var enabled = anything === true || extension . storage . get ( 'hide_watched_videos' ) === true ;
712+ var selector = [
713+ 'ytd-compact-video-renderer' ,
714+ 'ytd-rich-item-renderer' ,
715+ 'ytd-video-renderer' ,
716+ 'ytd-grid-video-renderer' ,
717+ 'ytd-playlist-video-renderer' ,
718+ 'ytd-reel-item-renderer'
719+ ] . join ( ',' ) ;
720+
721+ function getVideoId ( renderer ) {
722+ var link = renderer . querySelector ( 'a[href*="/watch"], a[href*="/shorts/"]' ) ;
723+ var href = link && link . href ;
724+
725+ if ( ! href ) {
726+ return '' ;
727+ }
728+
729+ var queryId = extension . functions . getUrlParameter ( href , 'v' ) ;
730+
731+ if ( queryId ) {
732+ return queryId ;
733+ }
734+
735+ var shortsMatch = href . match ( / \/ s h o r t s \/ ( [ ^ ? & / ] + ) / ) ;
736+
737+ return shortsMatch ? shortsMatch [ 1 ] : '' ;
738+ }
739+
740+ function getWatchedPercent ( renderer ) {
741+ if ( renderer . querySelector ( 'ytd-thumbnail-overlay-watched-status-renderer' ) ) {
742+ return 100 ;
743+ }
744+
745+ var progress = renderer . querySelector ( 'ytd-thumbnail-overlay-resume-playback-renderer #progress, #progress.ytd-thumbnail-overlay-resume-playback-renderer' ) ;
746+
747+ if ( progress && progress . style && progress . style . width ) {
748+ var width = parseFloat ( progress . style . width ) ;
749+
750+ if ( ! Number . isNaN ( width ) ) {
751+ return width ;
752+ }
753+ }
754+
755+ var videoId = getVideoId ( renderer ) ;
756+ var watched = extension . storage . get ( 'watched' ) ;
757+
758+ if ( videoId && watched && watched [ videoId ] ) {
759+ return 100 ;
760+ }
761+
762+ return 0 ;
763+ }
764+
765+ function apply ( ) {
766+ var threshold = parseInt ( extension . storage . get ( 'hide_watched_videos_threshold' ) , 10 ) ;
767+
768+ if ( Number . isNaN ( threshold ) ) {
769+ threshold = 90 ;
770+ }
771+
772+ threshold = Math . max ( 1 , Math . min ( 100 , threshold ) ) ;
773+
774+ document . querySelectorAll ( selector ) . forEach ( function ( renderer ) {
775+ var hide = enabled && getWatchedPercent ( renderer ) >= threshold ;
776+
777+ renderer . toggleAttribute ( 'it-hide-watched-video' , hide ) ;
778+ } ) ;
779+ }
780+
781+ if ( extension . features . hideWatchedVideos . observer ) {
782+ extension . features . hideWatchedVideos . observer . disconnect ( ) ;
783+ extension . features . hideWatchedVideos . observer = null ;
784+ }
785+
786+ apply ( ) ;
787+
788+ if ( enabled ) {
789+ var scheduled = false ;
790+ var schedule = function ( ) {
791+ if ( scheduled ) {
792+ return ;
793+ }
794+
795+ scheduled = true ;
796+ requestAnimationFrame ( function ( ) {
797+ scheduled = false ;
798+ apply ( ) ;
799+ } ) ;
800+ } ;
801+
802+ extension . features . hideWatchedVideos . observer = new MutationObserver ( schedule ) ;
803+ extension . features . hideWatchedVideos . observer . observe ( document . documentElement , {
804+ childList : true ,
805+ subtree : true ,
806+ attributes : true ,
807+ attributeFilter : [ 'style' ]
808+ } ) ;
809+ }
810+ } ;
811+
812+ extension . features . hideWatchedVideosThreshold = extension . features . hideWatchedVideos ;
813+
706814/*--------------------------------------------------------------
707815# THUMBNAILS QUALITY
708816--------------------------------------------------------------*/
0 commit comments