public.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import loadPolyfills from '../mastodon/load_polyfills';
  2. import ready from '../mastodon/ready';
  3. window.addEventListener('message', e => {
  4. const data = e.data || {};
  5. if (!window.parent || data.type !== 'setHeight') {
  6. return;
  7. }
  8. ready(() => {
  9. window.parent.postMessage({
  10. type: 'setHeight',
  11. id: data.id,
  12. height: document.getElementsByTagName('html')[0].scrollHeight,
  13. }, '*');
  14. });
  15. });
  16. function main() {
  17. const { length } = require('stringz');
  18. const IntlRelativeFormat = require('intl-relativeformat').default;
  19. const { delegate } = require('rails-ujs');
  20. const emojify = require('../mastodon/emoji').default;
  21. const { getLocale } = require('../mastodon/locales');
  22. const { localeData } = getLocale();
  23. const VideoContainer = require('../mastodon/containers/video_container').default;
  24. const MediaGalleryContainer = require('../mastodon/containers/media_gallery_container').default;
  25. const CardContainer = require('../mastodon/containers/card_container').default;
  26. const React = require('react');
  27. const ReactDOM = require('react-dom');
  28. localeData.forEach(IntlRelativeFormat.__addLocaleData);
  29. ready(() => {
  30. const locale = document.documentElement.lang;
  31. const dateTimeFormat = new Intl.DateTimeFormat(locale, {
  32. year: 'numeric',
  33. month: 'long',
  34. day: 'numeric',
  35. hour: 'numeric',
  36. minute: 'numeric',
  37. });
  38. const relativeFormat = new IntlRelativeFormat(locale);
  39. [].forEach.call(document.querySelectorAll('.emojify'), (content) => {
  40. content.innerHTML = emojify(content.innerHTML);
  41. });
  42. [].forEach.call(document.querySelectorAll('time.formatted'), (content) => {
  43. const datetime = new Date(content.getAttribute('datetime'));
  44. const formattedDate = dateTimeFormat.format(datetime);
  45. content.title = formattedDate;
  46. content.textContent = formattedDate;
  47. });
  48. [].forEach.call(document.querySelectorAll('time.time-ago'), (content) => {
  49. const datetime = new Date(content.getAttribute('datetime'));
  50. content.title = dateTimeFormat.format(datetime);
  51. content.textContent = relativeFormat.format(datetime);
  52. });
  53. [].forEach.call(document.querySelectorAll('.logo-button'), (content) => {
  54. content.addEventListener('click', (e) => {
  55. e.preventDefault();
  56. window.open(e.target.href, 'mastodon-intent', 'width=400,height=400,resizable=no,menubar=no,status=no,scrollbars=yes');
  57. });
  58. });
  59. [].forEach.call(document.querySelectorAll('[data-component="Video"]'), (content) => {
  60. const props = JSON.parse(content.getAttribute('data-props'));
  61. ReactDOM.render(<VideoContainer locale={locale} {...props} />, content);
  62. });
  63. [].forEach.call(document.querySelectorAll('[data-component="MediaGallery"]'), (content) => {
  64. const props = JSON.parse(content.getAttribute('data-props'));
  65. ReactDOM.render(<MediaGalleryContainer locale={locale} {...props} />, content);
  66. });
  67. [].forEach.call(document.querySelectorAll('[data-component="Card"]'), (content) => {
  68. const props = JSON.parse(content.getAttribute('data-props'));
  69. ReactDOM.render(<CardContainer locale={locale} {...props} />, content);
  70. });
  71. });
  72. delegate(document, '.webapp-btn', 'click', ({ target, button }) => {
  73. if (button !== 0) {
  74. return true;
  75. }
  76. window.location.href = target.href;
  77. return false;
  78. });
  79. delegate(document, '.status__content__spoiler-link', 'click', ({ target }) => {
  80. const contentEl = target.parentNode.parentNode.querySelector('.e-content');
  81. if (contentEl.style.display === 'block') {
  82. contentEl.style.display = 'none';
  83. target.parentNode.style.marginBottom = 0;
  84. } else {
  85. contentEl.style.display = 'block';
  86. target.parentNode.style.marginBottom = null;
  87. }
  88. return false;
  89. });
  90. delegate(document, '.account_display_name', 'input', ({ target }) => {
  91. const nameCounter = document.querySelector('.name-counter');
  92. if (nameCounter) {
  93. nameCounter.textContent = 30 - length(target.value);
  94. }
  95. });
  96. delegate(document, '.account_note', 'input', ({ target }) => {
  97. const noteCounter = document.querySelector('.note-counter');
  98. if (noteCounter) {
  99. noteCounter.textContent = 160 - length(target.value);
  100. }
  101. });
  102. delegate(document, '#account_avatar', 'change', ({ target }) => {
  103. const avatar = document.querySelector('.card.compact .avatar img');
  104. const [file] = target.files || [];
  105. const url = file ? URL.createObjectURL(file) : avatar.dataset.originalSrc;
  106. avatar.src = url;
  107. });
  108. delegate(document, '#account_header', 'change', ({ target }) => {
  109. const header = document.querySelector('.card.compact');
  110. const [file] = target.files || [];
  111. const url = file ? URL.createObjectURL(file) : header.dataset.originalSrc;
  112. header.style.backgroundImage = `url(${url})`;
  113. });
  114. }
  115. loadPolyfills().then(main).catch(error => {
  116. console.error(error);
  117. });