main.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*!
  2. * Hugo Theme Stack
  3. *
  4. * @author: Jimmy Cai
  5. * @website: https://jimmycai.com
  6. * @link: https://github.com/CaiJimmy/hugo-theme-stack
  7. */
  8. import StackGallery from "ts/gallery";
  9. import { getColor } from 'ts/color';
  10. import menu from 'ts/menu';
  11. import createElement from 'ts/createElement';
  12. import StackColorScheme from 'ts/colorScheme';
  13. import { setupScrollspy } from 'ts/scrollspy';
  14. import { setupSmoothAnchors } from "ts/smoothAnchors";
  15. let Stack = {
  16. init: () => {
  17. /**
  18. * Bind menu event
  19. */
  20. menu();
  21. const articleContent = document.querySelector('.article-content') as HTMLElement;
  22. if (articleContent) {
  23. new StackGallery(articleContent);
  24. setupSmoothAnchors();
  25. setupScrollspy();
  26. }
  27. /**
  28. * Add linear gradient background to tile style article
  29. */
  30. const articleTile = document.querySelector('.article-list--tile');
  31. if (articleTile) {
  32. let observer = new IntersectionObserver(async (entries, observer) => {
  33. entries.forEach(entry => {
  34. if (!entry.isIntersecting) return;
  35. observer.unobserve(entry.target);
  36. const articles = entry.target.querySelectorAll('article.has-image');
  37. articles.forEach(async articles => {
  38. const image = articles.querySelector('img'),
  39. imageURL = image.src,
  40. key = image.getAttribute('data-key'),
  41. hash = image.getAttribute('data-hash'),
  42. articleDetails: HTMLDivElement = articles.querySelector('.article-details');
  43. const colors = await getColor(key, hash, imageURL);
  44. articleDetails.style.background = `
  45. linear-gradient(0deg,
  46. rgba(${colors.DarkMuted.rgb[0]}, ${colors.DarkMuted.rgb[1]}, ${colors.DarkMuted.rgb[2]}, 0.5) 0%,
  47. rgba(${colors.Vibrant.rgb[0]}, ${colors.Vibrant.rgb[1]}, ${colors.Vibrant.rgb[2]}, 0.75) 100%)`;
  48. })
  49. })
  50. });
  51. observer.observe(articleTile)
  52. }
  53. /**
  54. * Add copy button to code block
  55. */
  56. const highlights = document.querySelectorAll('.article-content div.highlight');
  57. const copyText = `Copy`,
  58. copiedText = `Copied!`;
  59. highlights.forEach(highlight => {
  60. const copyButton = document.createElement('button');
  61. copyButton.innerHTML = copyText;
  62. copyButton.classList.add('copyCodeButton');
  63. highlight.appendChild(copyButton);
  64. const codeBlock = highlight.querySelector('code[data-lang]');
  65. if (!codeBlock) return;
  66. copyButton.addEventListener('click', () => {
  67. navigator.clipboard.writeText(codeBlock.textContent)
  68. .then(() => {
  69. copyButton.textContent = copiedText;
  70. setTimeout(() => {
  71. copyButton.textContent = copyText;
  72. }, 1000);
  73. })
  74. .catch(err => {
  75. alert(err)
  76. console.log('Something went wrong', err);
  77. });
  78. });
  79. });
  80. new StackColorScheme(document.getElementById('dark-mode-toggle'));
  81. }
  82. }
  83. window.addEventListener('load', () => {
  84. setTimeout(function () {
  85. Stack.init();
  86. }, 0);
  87. })
  88. declare global {
  89. interface Window {
  90. createElement: any;
  91. Stack: any
  92. }
  93. }
  94. window.Stack = Stack;
  95. window.createElement = createElement;