index.ts 3.7 KB

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