index.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import { addGlobalStyle, autoPlural, preloadImages, initOnSelector, onSelector } from "@sv443-network/userutils";
  2. import { loadFeatureConf } from "./config";
  3. import { logLevel, scriptInfo } from "./constants";
  4. import { error, getAssetUrl, getDomain, log, setLogLevel } from "./utils";
  5. import { initSiteEvents } from "./events";
  6. import {
  7. // layout
  8. initQueueButtons, addWatermark,
  9. preInitLayout, removeUpgradeTab, setVolSliderSize,
  10. setVolSliderStep,
  11. // lyrics
  12. addMediaCtrlLyricsBtn, geniUrlBase,
  13. // input
  14. initArrowKeySkip, initSiteSwitch, addAnchorImprovements,
  15. // menu
  16. initMenu, addMenu, initBeforeUnloadHook, addConfigMenuOption, addVolumeSliderLabel,
  17. } from "./features/index";
  18. /** URLs of images to pre-cache so they can be displayed instantly */
  19. const preloadImgs = [
  20. getAssetUrl("icon/icon.png"),
  21. getAssetUrl("spinner.svg"),
  22. getAssetUrl("delete.svg"),
  23. getAssetUrl("lyrics.svg"),
  24. ];
  25. {
  26. // console watermark with sexy gradient
  27. const styleGradient = "background: rgba(165, 38, 38, 1); background: linear-gradient(90deg, rgb(154, 31, 103) 0%, rgb(135, 31, 31) 40%, rgb(184, 64, 41) 100%);";
  28. const styleCommon = "color: #fff; font-size: 1.35em; padding-left: 6px; padding-right: 6px;";
  29. console.log();
  30. console.log(
  31. `%c${scriptInfo.name}%cv${scriptInfo.version}%c\n\nBuild #${scriptInfo.lastCommit} ─ ${scriptInfo.namespace}`,
  32. `font-weight: bold; ${styleCommon} ${styleGradient}`,
  33. `background-color: #333; ${styleCommon}`,
  34. "padding: initial;",
  35. );
  36. console.log([
  37. "Powered by:",
  38. "─ lots of ambition",
  39. `─ my song metadata API: ${geniUrlBase}`,
  40. "─ my userscript utility library: https://github.com/Sv443-Network/UserUtils",
  41. "─ this tiny event listener library: https://github.com/billjs/event-emitter",
  42. ].join("\n"));
  43. console.log();
  44. }
  45. const domain = getDomain();
  46. /** Stuff that needs to be called ASAP, before anything async happens */
  47. function preInit() {
  48. setLogLevel(logLevel);
  49. if(domain === "ytm")
  50. initBeforeUnloadHook();
  51. init();
  52. }
  53. async function init() {
  54. if(domain === "ytm")
  55. preloadImages(preloadImgs, true)
  56. .then(() => log(`Preloaded ${preloadImgs.length} ${autoPlural("image", preloadImgs)}`))
  57. .catch((e) => error(`Couldn't preload images: ${e}`));
  58. await preInitLayout();
  59. try {
  60. document.addEventListener("DOMContentLoaded", onDomLoad);
  61. }
  62. catch(err) {
  63. error("General Error:", err);
  64. }
  65. try {
  66. void ["TODO(v1.1):", initMenu];
  67. // initMenu();
  68. }
  69. catch(err) {
  70. error("Couldn't initialize menu:", err);
  71. }
  72. }
  73. /** Called when the DOM has finished loading and can be queried and altered by the userscript */
  74. async function onDomLoad() {
  75. // post-build these double quotes are replaced by backticks (because if backticks are used here, webpack converts them to double quotes)
  76. addGlobalStyle("{{GLOBAL_STYLE}}");
  77. initOnSelector();
  78. const features = await loadFeatureConf();
  79. log(`Initializing features for domain "${domain}"...`);
  80. try {
  81. if(domain === "ytm") {
  82. try {
  83. addMenu(); // TODO(v1.1): remove
  84. }
  85. catch(err) {
  86. error("Couldn't add menu:", err);
  87. }
  88. initSiteEvents();
  89. onSelector("tp-yt-iron-dropdown #contentWrapper ytd-multi-page-menu-renderer #container.menu-container", { listener: addConfigMenuOption });
  90. if(features.arrowKeySupport)
  91. initArrowKeySkip();
  92. if(features.removeUpgradeTab)
  93. removeUpgradeTab();
  94. if(features.watermarkEnabled)
  95. addWatermark();
  96. if(features.geniusLyrics)
  97. addMediaCtrlLyricsBtn();
  98. if(features.queueButtons)
  99. initQueueButtons();
  100. if(features.volumeSliderLabel)
  101. addVolumeSliderLabel();
  102. if(typeof features.volumeSliderSize === "number")
  103. setVolSliderSize();
  104. if(features.anchorImprovements)
  105. addAnchorImprovements();
  106. setVolSliderStep();
  107. }
  108. if(["ytm", "yt"].includes(domain)) {
  109. if(features.switchBetweenSites)
  110. initSiteSwitch(domain);
  111. }
  112. }
  113. catch(err) {
  114. error("General error while executing feature:", err);
  115. }
  116. }
  117. preInit();