Better DGG Kick Embed

24/02/2025, 21:06:45 Hacky solution to embed full kick site instead of the embed. I can't promise it will continue to work indefinitely. If it bugs out when resizing the window, try refreshing the page.

当前为 2025-02-25 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Better DGG Kick Embed
  3. // @namespace yuniDev.kickembed
  4. // @match https://kick.com/*
  5. // @match https://www.destiny.gg/bigscreen
  6. // @match https://destiny.gg/bigscreen
  7. // @grant none
  8. // @version 1.1
  9. // @author yuniDev
  10. // @license MIT
  11. // @description 24/02/2025, 21:06:45 Hacky solution to embed full kick site instead of the embed. I can't promise it will continue to work indefinitely. If it bugs out when resizing the window, try refreshing the page.
  12. // ==/UserScript==
  13.  
  14. let prevHash = "";
  15.  
  16. function htmlToNode(html) {
  17. const template = document.createElement('template');
  18. template.innerHTML = html;
  19. const nNodes = template.content.childNodes.length;
  20. return template.content.firstChild;
  21. }
  22.  
  23. function hideSurroundings() {
  24. [...document.querySelectorAll("nav")].forEach(el => el.style = "display: none;");
  25. const channelChatroom = document.getElementById("channel-chatroom");
  26. if (channelChatroom) channelChatroom.style = "display: none";
  27.  
  28. const sidebarWrapper = document.getElementById("sidebar-wrapper");
  29. if (sidebarWrapper) sidebarWrapper.style = "display: none";
  30.  
  31. const channelContent = document.getElementById("channel-content");
  32. if (channelContent) channelContent.style = "display: none";
  33.  
  34. const injectedChannelPlayer = document.getElementById("injected-channel-player");
  35. if (injectedChannelPlayer) {
  36. injectedChannelPlayer.style = "padding: 0px; max-height: max-content;";
  37. injectedChannelPlayer.parentNode.style = "max-height: max-content;";
  38. }
  39.  
  40. const bodyChild = document.body.firstChild;
  41. if (bodyChild) {
  42. bodyChild.style = "height: min-content;";
  43. [...bodyChild.children].forEach(el => el.style = el.getAttribute("style") ?? "" + ";padding-top: 0px;");
  44. }
  45. document.body.style = "height: min-content;";
  46. }
  47.  
  48. function loadDestinyGG() {
  49. const { origin, hash } = window.location;
  50.  
  51. if (prevHash.startsWith("#kick/") && !hash.startsWith("#kick")) location.reload(); // Reload page if switching away from kick embed
  52. prevHash = hash;
  53.  
  54. // Check if the URL starts with the desired base
  55. const isValidStart = hash.startsWith("#kick/") && window.location.pathname === "/bigscreen";
  56.  
  57. // Extract the channel name
  58. const channel = isValidStart ? hash.split("/")[1] : null;
  59.  
  60. if (channel && isValidStart) { // We are watching a kick embed on Destiny.gg
  61. document.body.appendChild(htmlToNode(`<script type="module" src="https://unpkg.com/x-frame-bypass"></script>`));
  62. const targetUrl = `https://kick.com/${channel}`;
  63.  
  64. id = setInterval(() => {
  65. const embedContainer = document.getElementById("embed");
  66. const existingIframe = embedContainer.querySelector(".embed-frame");
  67. if (!existingIframe) return;
  68.  
  69. existingIframe.remove();
  70.  
  71. clearInterval(id);
  72.  
  73. const iframe = htmlToNode(`<iframe is="x-frame-bypass" class="embed-frame" src="${targetUrl}" allow="fullscreen; autoplay; encrypted-media; picture-in-picture; web-share"></iframe>`);
  74. embedContainer.appendChild(iframe);
  75. }, 100);
  76. }
  77. }
  78.  
  79. if (window.location.hostname === "kick.com" && window.self !== window.top) { // Kick inside of iframe
  80. hideSurroundings();
  81. setInterval(() => {
  82. if (![...document.querySelectorAll("nav")].find(el => el.getAttribute("style") && el.getAttribute("style").indexOf("display: none") > -1)) hideSurroundings();
  83. }, 200);
  84. } else {
  85. loadDestinyGG();
  86. addEventListener('hashchange', loadDestinyGG);
  87. }