You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
5.2 KiB

  1. import loadPolyfills from '../mastodon/load_polyfills';
  2. import ready from '../mastodon/ready';
  3. import { start } from '../mastodon/common';
  4. start();
  5. window.addEventListener('message', e => {
  6. const data = e.data || {};
  7. if (!window.parent || data.type !== 'setHeight') {
  8. return;
  9. }
  10. ready(() => {
  11. window.parent.postMessage({
  12. type: 'setHeight',
  13. id: data.id,
  14. height: document.getElementsByTagName('html')[0].scrollHeight,
  15. }, '*');
  16. });
  17. });
  18. function main() {
  19. const { length } = require('stringz');
  20. const IntlMessageFormat = require('intl-messageformat').default;
  21. const { timeAgoString } = require('../mastodon/components/relative_timestamp');
  22. const { delegate } = require('rails-ujs');
  23. const emojify = require('../mastodon/features/emoji/emoji').default;
  24. const { getLocale } = require('../mastodon/locales');
  25. const { messages } = getLocale();
  26. const React = require('react');
  27. const ReactDOM = require('react-dom');
  28. const Rellax = require('rellax');
  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. [].forEach.call(document.querySelectorAll('.emojify'), (content) => {
  39. content.innerHTML = emojify(content.innerHTML);
  40. });
  41. [].forEach.call(document.querySelectorAll('time.formatted'), (content) => {
  42. const datetime = new Date(content.getAttribute('datetime'));
  43. const formattedDate = dateTimeFormat.format(datetime);
  44. content.title = formattedDate;
  45. content.textContent = formattedDate;
  46. });
  47. [].forEach.call(document.querySelectorAll('time.time-ago'), (content) => {
  48. const datetime = new Date(content.getAttribute('datetime'));
  49. const now = new Date();
  50. content.title = dateTimeFormat.format(datetime);
  51. content.textContent = timeAgoString({
  52. formatMessage: ({ id, defaultMessage }, values) => (new IntlMessageFormat(messages[id] || defaultMessage, locale)).format(values),
  53. formatDate: (date, options) => (new Intl.DateTimeFormat(locale, options)).format(date),
  54. }, datetime, now, datetime.getFullYear());
  55. });
  56. [].forEach.call(document.querySelectorAll('.modal-button'), (content) => {
  57. content.addEventListener('click', (e) => {
  58. e.preventDefault();
  59. window.open(e.target.href, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
  60. });
  61. });
  62. const reactComponents = document.querySelectorAll('[data-component]');
  63. if (reactComponents.length > 0) {
  64. import(/* webpackChunkName: "containers/media_container" */ '../mastodon/containers/media_container')
  65. .then(({ default: MediaContainer }) => {
  66. const content = document.createElement('div');
  67. ReactDOM.render(<MediaContainer locale={locale} components={reactComponents} />, content);
  68. document.body.appendChild(content);
  69. })
  70. .catch(error => console.error(error));
  71. }
  72. new Rellax('.parallax', { speed: -1 });
  73. });
  74. delegate(document, '.webapp-btn', 'click', ({ target, button }) => {
  75. if (button !== 0) {
  76. return true;
  77. }
  78. window.location.href = target.href;
  79. return false;
  80. });
  81. delegate(document, '.status__content__spoiler-link', 'click', ({ target }) => {
  82. const contentEl = target.parentNode.parentNode.querySelector('.e-content');
  83. if (contentEl.style.display === 'block') {
  84. contentEl.style.display = 'none';
  85. target.parentNode.style.marginBottom = 0;
  86. } else {
  87. contentEl.style.display = 'block';
  88. target.parentNode.style.marginBottom = null;
  89. }
  90. return false;
  91. });
  92. delegate(document, '#account_display_name', 'input', ({ target }) => {
  93. const nameCounter = document.querySelector('.name-counter');
  94. const name = document.querySelector('.card .display-name strong');
  95. if (nameCounter) {
  96. nameCounter.textContent = 30 - length(target.value);
  97. }
  98. if (name) {
  99. name.innerHTML = emojify(target.value);
  100. }
  101. });
  102. delegate(document, '#account_note', 'input', ({ target }) => {
  103. const noteCounter = document.querySelector('.note-counter');
  104. if (noteCounter) {
  105. noteCounter.textContent = 160 - length(target.value);
  106. }
  107. });
  108. delegate(document, '#account_avatar', 'change', ({ target }) => {
  109. const avatar = document.querySelector('.card .avatar img');
  110. const [file] = target.files || [];
  111. const url = file ? URL.createObjectURL(file) : avatar.dataset.originalSrc;
  112. avatar.src = url;
  113. });
  114. delegate(document, '#account_header', 'change', ({ target }) => {
  115. const header = document.querySelector('.card .card__img img');
  116. const [file] = target.files || [];
  117. const url = file ? URL.createObjectURL(file) : header.dataset.originalSrc;
  118. header.src = url;
  119. });
  120. delegate(document, '#account_locked', 'change', ({ target }) => {
  121. const lock = document.querySelector('.card .display-name i');
  122. if (target.checked) {
  123. lock.style.display = 'inline';
  124. } else {
  125. lock.style.display = 'none';
  126. }
  127. });
  128. }
  129. loadPolyfills().then(main).catch(error => {
  130. console.error(error);
  131. });