您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Show images/video in chat,Auto click claim bonus, hide offline channels, always source quality and more
当前为
// ==UserScript== // @name Enhance twitch // @namespace http://tampermonkey.net/ // @version 1.9.2 // @description Show images/video in chat,Auto click claim bonus, hide offline channels, always source quality and more // @author Bum // @require http://code.jquery.com/jquery-3.4.1.min.js // @match https://www.twitch.tv/* // @match https://clips.twitch.tv/* // @grant none // ==/UserScript== var alwaysSourceQuality = "true"; var displayImages = "true"; var displayVideos = "true"; var autoPlayClips = "false"; var hideHypeTrain = "false"; var hideBitGiftLeaderBoard = "false"; var hideUnfollowButton = "false"; var ultraWide = "true"; var hideOfflineChannels = "true"; var hideRecommendedChannels = "true"; if (localStorage.getItem("hideRecommendedChannels") != null) { hideRecommendedChannels = localStorage.getItem("hideRecommendedChannels"); } if (localStorage.getItem("displayImages") != null) { displayImages = localStorage.getItem("displayImages"); } if (localStorage.getItem("hideOfflineChannels") != null) { hideOfflineChannels = localStorage.getItem("hideOfflineChannels"); } if (localStorage.getItem("displayVideos") != null) { displayVideos = localStorage.getItem("displayVideos"); } if (localStorage.getItem("alwaysSourceQuality") != null) { alwaysSourceQuality = localStorage.getItem("alwaysSourceQuality"); } if (localStorage.getItem("autoPlayClips") != null) { autoPlayClips = localStorage.getItem("autoPlayClips"); } if (localStorage.getItem("hideHypeTrain") != null) { hideHypeTrain = localStorage.getItem("hideHypeTrain"); } if (localStorage.getItem("hideBitGiftLeaderBoard") != null) { hideBitGiftLeaderBoard = localStorage.getItem("hideBitGiftLeaderBoard"); } if (localStorage.getItem("hideUnfollowButton") != null) { hideUnfollowButton = localStorage.getItem("hideUnfollowButton"); } if (localStorage.getItem("ultraWide") != null) { ultraWide = localStorage.getItem("ultraWide"); } if (ultraWide == "true"){ GM_addStyle(".browse-root-page__wrapper{ left: 0; position: relative; width: 100%; max-width: 10000px;}"); } function GM_addStyle(css) { const style = document.getElementById("GM_addStyle") || (function() { const style = document.createElement('style'); style.type = 'text/css'; style.id = "GM_addStyle"; document.head.appendChild(style); return style; })(); const sheet = style.sheet; sheet.insertRule(css, (sheet.rules || sheet.cssRules || []).length); } $( window ).on( "load", function() { if (hideUnfollowButton == "true") GM_addStyle('button[data-a-target="unfollow-button"]{display: none !important;}'); }); function RemoveCssRule(css) { const style = document.getElementById("GM_addStyle") || (function() { const style = document.createElement('style'); style.type = 'text/css'; style.id = "GM_addStyle"; document.head.appendChild(style); return style; })(); const sheet = style.sheet; for (var i=0; i<sheet.cssRules.length; i++) { if (sheet.cssRules[i].selectorText == css) { sheet.deleteRule (i); } } } function LoadTwitchEnhance(){ var config = { attributes: false, childList: true, subtree: true }; function getMenuItem(id, display, checked){ if (checked == "true"){ var res = '<div class="tw-pd-05"><div data-a-target="high-contrast-color-checkbox" class="tw-align-items-center tw-flex"><label class="tw-drop-down-menu-input-item__label tw-flex-grow-1 tw-mg-r-2" for="'+id+'">'+display+'</label><div class="tw-toggle" data-a-target="high-contrast-color-checkbox"><input type="checkbox" id="'+id+'" label="Readable Colors" class="tw-toggle__input" data-a-target="tw-toggle" checked=""><label for="'+id+'" class="tw-toggle__button"><p class="tw-hide-accessible">'+display+'</p></label></div></div></div>'; return res; } else{ var res2 = ' <div class="tw-pd-05"><div class="tw-align-items-center tw-flex"><label class="tw-drop-down-menu-input-item__label tw-flex-grow-1 tw-mg-r-2" for="'+id+'">'+display+'</label><div class="tw-toggle"><input type="checkbox" label="Subscribers-Only Chat" id="'+id+'" class="tw-toggle__input" data-a-target="tw-toggle"><label for="'+id+'" class="tw-toggle__button"><p class="tw-hide-accessible">'+display+'</p></label></div></div></div>'; return res2; } } function addMenu(){ var menu = $(".chat-settings__content"); var isReady = menu.length > 0; if (!isReady) { setTimeout(addMenu, 50); return; } if ($(".customEnhanceMenu").length > 0 ) return; menu.append('<div class="tw-border-t tw-mg-t-1 tw-mg-x-05 tw-pd-b-1 customEnhanceMenu"></div><div class="tw-mg-y-05 tw-pd-x-05"><p class="tw-c-text-alt-2 tw-font-size-6 tw-strong tw-upcase">Enhance Twitch</p></div>'); menu.append(getMenuItem('displayImages','Display Images', displayImages)); $("#displayImages").change(function() { localStorage.setItem("displayImages", this.checked); displayImages = localStorage.getItem("displayImages"); }); menu.append(getMenuItem('displayVideos','Display Videos',displayVideos)); $("#displayVideos").change(function() { localStorage.setItem("displayVideos", this.checked); displayVideos = localStorage.getItem("displayVideos"); }); menu.append(getMenuItem('alwaysSourceQuality','Always Source Quality',alwaysSourceQuality)); $("#alwaysSourceQuality").change(function() { localStorage.setItem("alwaysSourceQuality", this.checked); alwaysSourceQuality = localStorage.getItem("alwaysSourceQuality"); if (alwaysSourceQuality == "true") localStorage.setItem('video-quality', '{"default":"chunked"}'); }); menu.append(getMenuItem('autoPlayClips','Auto play clips',autoPlayClips)); $("#autoPlayClips").change(function() { localStorage.setItem("autoPlayClips", this.checked); autoPlayClips = localStorage.getItem("autoPlayClips"); }); //hideOfflineChannels menu.append(getMenuItem('fixhideOfflineChannels','Hide offline channels',hideOfflineChannels)); $("#fixhideOfflineChannels").change(function() { localStorage.setItem("hideOfflineChannels", this.checked); hideOfflineChannels = localStorage.getItem("hideOfflineChannels"); }); //hideRecommendedChannels menu.append(getMenuItem('fixhideRecommendedChannels','Hide Recommended channels',hideRecommendedChannels)); $("#fixhideRecommendedChannels").change(function() { localStorage.setItem("hideRecommendedChannels", this.checked); hideRecommendedChannels = localStorage.getItem("hideRecommendedChannels"); if (hideRecommendedChannels == "true") hideRecommendedChannelsPlease(); else{ $(".fixRecommendedChannelHidden").attr("style","display:block"); } }); menu.append(getMenuItem('hideHypeTrain','Hide hype train',hideHypeTrain)); $("#hideHypeTrain").change(function() { localStorage.setItem("hideHypeTrain", this.checked); hideHypeTrain = localStorage.getItem("hideHypeTrain"); if (hideHypeTrain == "false") RemoveCssRule(".community-highlight-stack__scroll-area--disable"); else GM_addStyle(".community-highlight-stack__scroll-area--disable{display: none !important;}"); }); menu.append(getMenuItem('hideBitGiftLeaderBoard','Hide gift/bit leaderboard',hideBitGiftLeaderBoard)); $("#hideBitGiftLeaderBoard").change(function() { localStorage.setItem("hideBitGiftLeaderBoard", this.checked); hideBitGiftLeaderBoard = localStorage.getItem("hideBitGiftLeaderBoard"); if (hideBitGiftLeaderBoard == "false") RemoveCssRule(".channel-leaderboard"); else GM_addStyle(".channel-leaderboard{display: none !important;}"); }); menu.append(getMenuItem('hideUnfollowButton','Hide unfollow button',hideUnfollowButton)); $("#hideUnfollowButton").change(function() { localStorage.setItem("hideUnfollowButton", this.checked); hideUnfollowButton = localStorage.getItem("hideUnfollowButton"); if (hideUnfollowButton == "false") RemoveCssRule('button[data-a-target="unfollow-button"]'); else GM_addStyle('button[data-a-target="unfollow-button"]{display: none !important;}'); }); } var SupportedImageFormats = [".jpg", ".jpeg", ".png", ".webp", ".gif"]; var SupportedVideoFormats = [".mp4",".webm"]; var maxHeight = "240"; var maxWidth = "300"; GM_addStyle("iframe[class^='imgur-embed']{max-width: "+maxWidth+"px !important;}"); GM_addStyle("svg[class*='logotwitchwordmark']{display: none !important;}"); if (hideHypeTrain == "true") GM_addStyle(".community-highlight-stack__scroll-area--disable{display: none !important;}"); if (hideBitGiftLeaderBoard == "true") GM_addStyle(".channel-leaderboard{display: none !important;}"); GM_addStyle(".btnRefreshEnhance button{height: 15px; width: 100%}"); GM_addStyle(".chat-settings{ max-height: 500px !important; overflow: hidden !important;}"); function isSupportedImage(url) { var length = SupportedImageFormats.length; while(length--) { if (url.indexOf(SupportedImageFormats[length])!=-1) { return true; } } return false; } function isSupportedVideo(url) { var length = SupportedVideoFormats.length; while(length--) { if (url.indexOf(SupportedVideoFormats[length])!=-1) { return true; } } return false; } function alterNode(node) { var thisUrl = $(node).text(); var parentToScroll = $(node).parent().parent().parent().parent(); if (displayImages == "true" && isSupportedImage(thisUrl)){ $(node).html("<br><img src='" + thisUrl + "' width='" + maxWidth +"px'/>"); parentToScroll.animate({scrollTop:parentToScroll.scrollTop() + 500}, 'slow'); } else if (displayVideos == "true" && thisUrl.indexOf("www.youtube") > 0 ){ if (thisUrl.indexOf("watch") > 0){ var videoId = thisUrl.match('v=([^&]*)')[1]; $(node).html('<br><iframe width="'+ maxWidth +'" height="'+ maxHeight +'" src="https://www.youtube.com/embed/' + videoId+'"></iframe>'); parentToScroll.animate({scrollTop:parentToScroll.scrollTop() + 500}, 'slow'); } } else if (displayVideos == "true" && isSupportedVideo(thisUrl)){ $(node).html('<br><video width="'+ maxWidth +'" height="'+ maxHeight +'" controls autoplay muted><source src="'+thisUrl +'" type="video/mp4"></video>'); parentToScroll.animate({scrollTop:parentToScroll.scrollTop() + 500}, 'slow'); } else if (displayImages == "true" && thisUrl.indexOf("https://gyazo.com") > -1 ){ $(node).html("<br><img src='" + thisUrl.replace("https://gyazo.com", "https://i.gyazo.com") +".png' width='" + maxWidth +"px'/>"); parentToScroll.animate({scrollTop:parentToScroll.scrollTop() + 500}, 'slow'); } else if (displayImages == "true" && thisUrl.indexOf("imgur") > -1){ var imgurId = ""; if (thisUrl.indexOf("gallery") > -1){ imgurId = thisUrl.match('gallery\/([^#]*)')[1]; try{ $(node).html('<div style="width:200"><blockquote class="imgur-embed-pub" lang="en" data-id="a/'+ imgurId +'"><a href="//imgur.com/'+ imgurId +'" ></a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script></div>'); } catch(err){ } } else{ imgurId = thisUrl.match('a\/([^#]*)')[1]; try{ $(node).html('<div style="width:200"><blockquote class="imgur-embed-pub" lang="en" data-id="a/'+ imgurId +'"><a href="//imgur.com/'+ imgurId +'" ></a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script></div>'); } catch(err){ } } parentToScroll.animate({scrollTop:parentToScroll.scrollTop() + 500}, 'slow'); } else if (displayVideos == "true" && thisUrl.indexOf("clips.twitch.tv") > -1){ var clipId = thisUrl.match('.tv\/(.*)')[1]; $(node).html('<iframe src="https://clips.twitch.tv/embed?clip='+clipId+'&autoplay='+autoPlayClips+'&muted=true&parent=twitch.tv" frameborder="0" allowfullscreen="true" height="'+maxHeight+'" width="'+maxWidth+'"></iframe>'); parentToScroll.animate({scrollTop:parentToScroll.scrollTop() + 500}, 'slow'); } else if (displayVideos == "true" && thisUrl.indexOf("twitch") > -1 && thisUrl.indexOf("clip") > -1){ var clipId1 = thisUrl.match('clip\/([^?]*)')[1]; $(node).html('<iframe src="https://clips.twitch.tv/embed?clip='+clipId1+'&autoplay='+autoPlayClips+'&muted=true&parent=twitch.tv" frameborder="0" allowfullscreen="true" height="'+maxHeight+'" width="'+maxWidth+'"></iframe>'); parentToScroll.animate({scrollTop:parentToScroll.scrollTop() + 500}, 'slow'); } } // Callback function to execute when mutations are observed var callback = function(mutationsList, observer) { for(var mutation of mutationsList) { mutation.addedNodes.forEach(function(node) { if (node.classList != undefined && node.classList.contains('link-fragment')) { alterNode(node); } if (node.querySelectorAll){ node.querySelectorAll('.link-fragment').forEach(function(node) { alterNode(node); }) node.querySelectorAll('.text-fragment').forEach(function(node) { alterNode(node); }) } }); } }; var callbackAddMenu = function(mutationsList, observer) { $('button[data-a-target="chat-settings"]:not(.fixMenuAppended)').click(function(){ $('button[data-a-target="chat-settings"]').addClass("fixMenuAppended"); addMenu(); }); }; var callbackClaim = function(mutationsList, observer) { for(var mutation of mutationsList) { $(".claimable-bonus__icon").click(); } }; var observerMenu = new MutationObserver(callbackAddMenu); // Create an observer instance linked to the callback function var observer = new MutationObserver(callback); function _appendObserver() { var isReady = $("div.chat-list").length > 0; if (!isReady) { setTimeout(_appendObserver, 500); return; } if (!$("div.chat-list").hasClass("enhanceAppended")){ $("div.chat-list").addClass("enhanceAppended"); var targetNode = $("div.chat-list").get(0); var targetNode2 = $(".right-column").get(0); // Start observing the target node for configured mutations observer.observe(targetNode, config); observerMenu.observe(targetNode2, config); } } _appendObserver(); function watchInSquad(){ $('button[data-a-player-state="playing"]').click(); $("main").children().each(function(){ $(this).attr("style","display:none !important;"); }); $(".right-column").parent().attr("style","display:none !important;"); var btnWatchInSquad = $("<button class = 'tw-align-items-center tw-align-middle tw-border-bottom-left-radius-medium tw-border-bottom-right-radius-medium tw-border-top-left-radius-medium tw-border-top-right-radius-medium tw-core-button tw-core-button--secondary tw-full-width tw-inline-flex tw-interactive tw-justify-content-center tw-overflow-hidden tw-relative'> Exit Squad Mode </button>"); btnWatchInSquad.addClass("enhanceTwitchAttached"); btnWatchInSquad.addClass("enhanceTwitchButtonSquadMode"); btnWatchInSquad.css("padding","10px"); $("main").append(btnWatchInSquad); btnWatchInSquad.click(function(event){ $("#enhanceSquadModeIframe").remove(); $("main").children().each(function(){ $(this).attr("style",""); }); $(".right-column").parent().attr("style",""); $(this).remove(); $('button[data-a-player-state="paused"]').click(); }); $('<iframe src="'+window.location.href + '/squad" frameborder="0" scrolling="no" id="enhanceSquadModeIframe" style="height:100%"></iframe>').appendTo('main'); } function exitSquadMode(){ if ( $("#enhanceSquadModeIframe").length > 0 && $("#enhanceSquadModeIframe").attr("src").indexOf(window.location.href) == -1){ $("#enhanceSquadModeIframe").remove(); $("main").children().each(function(){ $(this).attr("style",""); }); $(".right-column").parent().attr("style",""); $(".enhanceTwitchButtonSquadMode").remove(); $('button[data-a-player-state="paused"]').click(); }; }; function _addWatchInSquad(){ var elWatchInSquad = $('button[data-a-target="squad-stream-banner-button"]:not(.enhanceTwitchAttached)'); if (elWatchInSquad.length > 0){ var elSquad = elWatchInSquad.parent().parent(); elWatchInSquad.detach(); var streamingWith = elSquad.find(".tw-ellipsis").text(); var btnWatchInSquad = $("<button class = 'tw-align-items-center tw-align-middle tw-border-bottom-left-radius-medium tw-border-bottom-right-radius-medium tw-border-top-left-radius-medium tw-border-top-right-radius-medium tw-core-button tw-core-button--secondary tw-full-width tw-inline-flex tw-interactive tw-justify-content-center tw-overflow-hidden tw-relative'> Watch In Squad Mode </button>"); btnWatchInSquad.attr("data-toggle","tooltip"); btnWatchInSquad.attr("title",streamingWith); btnWatchInSquad.addClass("enhanceTwitchAttached"); btnWatchInSquad.css("margin-left","10px"); btnWatchInSquad.css("padding","10px"); $(".channel-header__right").append(btnWatchInSquad); elSquad.parent().css("display","none"); $(".persistent-player").css("top","0"); btnWatchInSquad.click(function(event){ watchInSquad(); }); return; }else{ var elPrevious = $('.enhanceTwitchAttached'); if (elPrevious.length > 0){ var streamerStr = $(".channel-header__avatar-dropdown").find("figure").attr("aria-label"); if (elPrevious.attr("title").indexOf(streamerStr) == -1) elPrevious.remove(); } } } var targetNodeRoot = document.getElementById('root'); var configRoot = { attributes: false, childList: true, subtree: true }; var callbackRoot = function(mutationsList, observer) { $(".claimable-bonus__icon").click(); _appendObserver(); var exitButton = $ ('button[data-a-target="squad-stream-exit-button"]:not(.enhanceTwitchAttached)'); if (exitButton.length> 0){ exitButton.attr("style","display: none !important"); exitButton.addClass("enhanceTwitchAttached"); } exitSquadMode(); if (hideOfflineChannels == "true"){ for(var mutation of mutationsList){ mutation.addedNodes.forEach(function(node) { //side-nav-card__avatar var channelStatus = $(node).find(".side-nav-card__avatar"); var offlineChannels = $(node).find(".side-nav-card__avatar--offline"); if (offlineChannels.length > 0){ var parentStatus = offlineChannels.parent(); parentStatus.attr("style","display:none !important;"); } if (channelStatus.length > 0){ var elemToObserve = channelStatus.get(0); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { var channelIsOffline = mutation.target.classList.contains('side-nav-card__avatar--offline'); var parentStatus = $($(mutation)[0].target).parent(); if(channelIsOffline){ parentStatus.attr("style", "display:none !important;"); } else{ parentStatus.attr("style","display:inherit !important;"); $('button[data-test-selector="ShowMore"]').click(); } }); }); observer.observe(elemToObserve, {attributes: true}); } }); } } if (window.location.href == "https://www.twitch.tv/"){ var videoMainPage = $(".featured-content-carousel:not(.fixVideoPausedOnce)").find("video"); if (videoMainPage.length > 0){ videoMainPage.get(0).pause(); videoMainPage.parent().click(function(){ $(".featured-content-carousel").addClass('fixVideoPausedOnce'); }); } } var linkArg = $(".social-media-space--content").find(".tw-avatar").attr("aria-label"); if ($(".social-media-space--content:not(.fixLinksAppended)").length > 0 || $(".social-media-space--content").attr("id") != "fix" + linkArg){ var appendable = $(".social-media-space--content").find('.tw-title').parent(); if (appendable.length>0) { $("#fixVideosLinks").remove(); $("#fixClipsLinks").remove(); $("#fixSpanLinks").remove(); appendable.append('<a target="_blank" id ="fixVideosLinks" href="/'+linkArg+'/videos"><span>Videos</span></a><span id = "fixSpanLinks"> / </span>'); appendable.append('<a target="_blank" id ="fixClipsLinks" href="/'+linkArg+'/clips?filter=clips&range=7d"><span>Clips</span></a>'); $(".social-media-space--content").addClass("fixLinksAppended"); $(".social-media-space--content").attr("id","fix"+linkArg); } } }; var callbackPlayer = function(mutationList,observer){ // disabled for now _addWatchInSquad(); } function appendPlayerObserver(){ var targetNodePlayer = $('.persistent-player'); var isReady = targetNodePlayer.length > 0; if (!isReady) { setTimeout(appendPlayerObserver, 500); return; } var observerPlayer = new MutationObserver(callbackPlayer); observerPlayer.observe(targetNodePlayer.get(0), config); } appendPlayerObserver(); // Create an observer instance linked to the callback function var observerroot = new MutationObserver(callbackRoot); // Start observing the target node for configured mutations observerroot.observe(targetNodeRoot, config); var callbackQuality = function(mutationsList, observer) { localStorage.setItem('video-quality', '{"default":"chunked"}'); }; function _appendQualityObserver() { var isReady = $('div[data-a-target="player-controls"]').length > 0; if (!isReady) { setTimeout(_appendQualityObserver, 500); return; } var targetNodeQuality = $('div[data-a-target="player-controls"]').get(0); var observerQuality = new MutationObserver(callbackQuality); observerQuality.observe(targetNodeQuality, config); } if (alwaysSourceQuality == "true"){ _appendQualityObserver(); Object.defineProperty(document, 'hidden', {value: false}); Object.defineProperty(document, 'visibilityState', {value: 'visible'}); } function hideRecommendedChannelsPlease(){ var getARecommendedChannel = $('a[data-a-target="recommended-channel"]'); var isReady = getARecommendedChannel.length > 0; if (!isReady) { setTimeout(hideRecommendedChannelsPlease, 500); return; } var closestParent = getARecommendedChannel.closest(".side-nav-section"); closestParent.attr("style","display:none"); closestParent.addClass("fixRecommendedChannelHidden"); } if (hideRecommendedChannels == "true"){ hideRecommendedChannelsPlease(); } } (function() { 'use strict'; LoadTwitchEnhance(); })();