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.

122 lines
3.3 KiB

  1. // Package imports.
  2. import classNames from 'classnames';
  3. import PropTypes from 'prop-types';
  4. import React from 'react';
  5. import {
  6. defineMessages,
  7. FormattedMessage,
  8. } from 'react-intl';
  9. import { length } from 'stringz';
  10. // Components.
  11. import Button from 'flavours/glitch/components/button';
  12. import Icon from 'flavours/glitch/components/icon';
  13. // Utils.
  14. import { maxChars } from 'flavours/glitch/util/initial_state';
  15. // Messages.
  16. const messages = defineMessages({
  17. publish: {
  18. defaultMessage: 'Toot',
  19. id: 'compose_form.publish',
  20. },
  21. publishLoud: {
  22. defaultMessage: '{publish}!',
  23. id: 'compose_form.publish_loud',
  24. },
  25. });
  26. // The component.
  27. export default function ComposerPublisher ({
  28. countText,
  29. disabled,
  30. intl,
  31. onSecondarySubmit,
  32. onSubmit,
  33. privacy,
  34. sideArm,
  35. }) {
  36. const diff = maxChars - length(countText || '');
  37. const computedClass = classNames('composer--publisher', {
  38. disabled: disabled || diff < 0,
  39. over: diff < 0,
  40. });
  41. // The result.
  42. return (
  43. <div className={computedClass}>
  44. <span className='count'>{diff}</span>
  45. {sideArm && sideArm !== 'none' ? (
  46. <Button
  47. className='side_arm'
  48. disabled={disabled || diff < 0}
  49. onClick={onSecondarySubmit}
  50. style={{ padding: null }}
  51. text={
  52. <span>
  53. <Icon
  54. icon={{
  55. public: 'globe',
  56. unlisted: 'unlock-alt',
  57. private: 'lock',
  58. direct: 'envelope',
  59. }[sideArm]}
  60. />
  61. </span>
  62. }
  63. title={`${intl.formatMessage(messages.publish)}: ${intl.formatMessage({ id: `privacy.${sideArm}.short` })}`}
  64. />
  65. ) : null}
  66. <Button
  67. className='primary'
  68. text={function () {
  69. switch (true) {
  70. case !!sideArm && sideArm !== 'none':
  71. case privacy === 'direct':
  72. case privacy === 'private':
  73. return (
  74. <span>
  75. <Icon
  76. icon={{
  77. direct: 'envelope',
  78. private: 'lock',
  79. public: 'globe',
  80. unlisted: 'unlock-alt',
  81. }[privacy]}
  82. />
  83. {' '}
  84. <FormattedMessage {...messages.publish} />
  85. </span>
  86. );
  87. case privacy === 'public':
  88. return (
  89. <span>
  90. <FormattedMessage
  91. {...messages.publishLoud}
  92. values={{ publish: <FormattedMessage {...messages.publish} /> }}
  93. />
  94. </span>
  95. );
  96. default:
  97. return <span><FormattedMessage {...messages.publish} /></span>;
  98. }
  99. }()}
  100. title={`${intl.formatMessage(messages.publish)}: ${intl.formatMessage({ id: `privacy.${privacy}.short` })}`}
  101. onClick={onSubmit}
  102. disabled={disabled || diff < 0}
  103. />
  104. </div>
  105. );
  106. }
  107. // Props.
  108. ComposerPublisher.propTypes = {
  109. countText: PropTypes.string,
  110. disabled: PropTypes.bool,
  111. intl: PropTypes.object.isRequired,
  112. onSecondarySubmit: PropTypes.func,
  113. onSubmit: PropTypes.func,
  114. privacy: PropTypes.oneOf(['direct', 'private', 'unlisted', 'public']),
  115. sideArm: PropTypes.oneOf(['none', 'direct', 'private', 'unlisted', 'public']),
  116. };