status_container.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. import React from 'react';
  2. import { connect } from 'react-redux';
  3. import Status from '../components/status';
  4. import { makeGetStatus, makeGetPictureInPicture } from '../selectors';
  5. import {
  6. replyCompose,
  7. mentionCompose,
  8. directCompose,
  9. } from '../actions/compose';
  10. import {
  11. reblog,
  12. favourite,
  13. bookmark,
  14. unreblog,
  15. unfavourite,
  16. unbookmark,
  17. pin,
  18. unpin,
  19. } from '../actions/interactions';
  20. import {
  21. muteStatus,
  22. unmuteStatus,
  23. deleteStatus,
  24. hideStatus,
  25. revealStatus,
  26. toggleStatusCollapse,
  27. editStatus,
  28. translateStatus,
  29. undoStatusTranslation,
  30. } from '../actions/statuses';
  31. import {
  32. unmuteAccount,
  33. unblockAccount,
  34. } from '../actions/accounts';
  35. import {
  36. blockDomain,
  37. unblockDomain,
  38. } from '../actions/domain_blocks';
  39. import {
  40. initAddFilter,
  41. } from '../actions/filters';
  42. import { initMuteModal } from '../actions/mutes';
  43. import { initBlockModal } from '../actions/blocks';
  44. import { initBoostModal } from '../actions/boosts';
  45. import { initReport } from '../actions/reports';
  46. import { openModal } from '../actions/modal';
  47. import { deployPictureInPicture } from '../actions/picture_in_picture';
  48. import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
  49. import { boostModal, deleteModal } from '../initial_state';
  50. import { showAlertForError } from '../actions/alerts';
  51. const messages = defineMessages({
  52. deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
  53. deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
  54. redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' },
  55. redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.' },
  56. replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
  57. replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
  58. blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Hide entire domain' },
  59. });
  60. const makeMapStateToProps = () => {
  61. const getStatus = makeGetStatus();
  62. const getPictureInPicture = makeGetPictureInPicture();
  63. const mapStateToProps = (state, props) => ({
  64. status: getStatus(state, props),
  65. pictureInPicture: getPictureInPicture(state, props),
  66. });
  67. return mapStateToProps;
  68. };
  69. const mapDispatchToProps = (dispatch, { intl, contextType }) => ({
  70. onReply (status, router) {
  71. dispatch((_, getState) => {
  72. let state = getState();
  73. if (state.getIn(['compose', 'text']).trim().length !== 0) {
  74. dispatch(openModal('CONFIRM', {
  75. message: intl.formatMessage(messages.replyMessage),
  76. confirm: intl.formatMessage(messages.replyConfirm),
  77. onConfirm: () => dispatch(replyCompose(status, router)),
  78. }));
  79. } else {
  80. dispatch(replyCompose(status, router));
  81. }
  82. });
  83. },
  84. onModalReblog (status, privacy) {
  85. if (status.get('reblogged')) {
  86. dispatch(unreblog(status));
  87. } else {
  88. dispatch(reblog(status, privacy));
  89. }
  90. },
  91. onReblog (status, e) {
  92. if ((e && e.shiftKey) || !boostModal) {
  93. this.onModalReblog(status);
  94. } else {
  95. dispatch(initBoostModal({ status, onReblog: this.onModalReblog }));
  96. }
  97. },
  98. onFavourite (status) {
  99. if (status.get('favourited')) {
  100. dispatch(unfavourite(status));
  101. } else {
  102. dispatch(favourite(status));
  103. }
  104. },
  105. onBookmark (status) {
  106. if (status.get('bookmarked')) {
  107. dispatch(unbookmark(status));
  108. } else {
  109. dispatch(bookmark(status));
  110. }
  111. },
  112. onPin (status) {
  113. if (status.get('pinned')) {
  114. dispatch(unpin(status));
  115. } else {
  116. dispatch(pin(status));
  117. }
  118. },
  119. onEmbed (status) {
  120. dispatch(openModal('EMBED', {
  121. url: status.get('url'),
  122. onError: error => dispatch(showAlertForError(error)),
  123. }));
  124. },
  125. onDelete (status, history, withRedraft = false) {
  126. if (!deleteModal) {
  127. dispatch(deleteStatus(status.get('id'), history, withRedraft));
  128. } else {
  129. dispatch(openModal('CONFIRM', {
  130. message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage),
  131. confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm),
  132. onConfirm: () => dispatch(deleteStatus(status.get('id'), history, withRedraft)),
  133. }));
  134. }
  135. },
  136. onEdit (status, history) {
  137. dispatch(editStatus(status.get('id'), history));
  138. },
  139. onTranslate (status) {
  140. if (status.get('translation')) {
  141. dispatch(undoStatusTranslation(status.get('id')));
  142. } else {
  143. dispatch(translateStatus(status.get('id')));
  144. }
  145. },
  146. onDirect (account, router) {
  147. dispatch(directCompose(account, router));
  148. },
  149. onMention (account, router) {
  150. dispatch(mentionCompose(account, router));
  151. },
  152. onOpenMedia (statusId, media, index) {
  153. dispatch(openModal('MEDIA', { statusId, media, index }));
  154. },
  155. onOpenVideo (statusId, media, options) {
  156. dispatch(openModal('VIDEO', { statusId, media, options }));
  157. },
  158. onBlock (status) {
  159. const account = status.get('account');
  160. dispatch(initBlockModal(account));
  161. },
  162. onUnblock (account) {
  163. dispatch(unblockAccount(account.get('id')));
  164. },
  165. onReport (status) {
  166. dispatch(initReport(status.get('account'), status));
  167. },
  168. onAddFilter (status) {
  169. dispatch(initAddFilter(status, { contextType }));
  170. },
  171. onMute (account) {
  172. dispatch(initMuteModal(account));
  173. },
  174. onUnmute (account) {
  175. dispatch(unmuteAccount(account.get('id')));
  176. },
  177. onMuteConversation (status) {
  178. if (status.get('muted')) {
  179. dispatch(unmuteStatus(status.get('id')));
  180. } else {
  181. dispatch(muteStatus(status.get('id')));
  182. }
  183. },
  184. onToggleHidden (status) {
  185. if (status.get('hidden')) {
  186. dispatch(revealStatus(status.get('id')));
  187. } else {
  188. dispatch(hideStatus(status.get('id')));
  189. }
  190. },
  191. onToggleCollapsed (status, isCollapsed) {
  192. dispatch(toggleStatusCollapse(status.get('id'), isCollapsed));
  193. },
  194. onBlockDomain (domain) {
  195. dispatch(openModal('CONFIRM', {
  196. message: <FormattedMessage id='confirmations.domain_block.message' defaultMessage='Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.' values={{ domain: <strong>{domain}</strong> }} />,
  197. confirm: intl.formatMessage(messages.blockDomainConfirm),
  198. onConfirm: () => dispatch(blockDomain(domain)),
  199. }));
  200. },
  201. onUnblockDomain (domain) {
  202. dispatch(unblockDomain(domain));
  203. },
  204. deployPictureInPicture (status, type, mediaProps) {
  205. dispatch(deployPictureInPicture(status.get('id'), status.getIn(['account', 'id']), type, mediaProps));
  206. },
  207. onInteractionModal (type, status) {
  208. dispatch(openModal('INTERACTION', {
  209. type,
  210. accountId: status.getIn(['account', 'id']),
  211. url: status.get('url'),
  212. }));
  213. },
  214. });
  215. export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(Status));