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.

100 lines
3.2 KiB

  1. // Package imports.
  2. import classNames from 'classnames';
  3. import PropTypes from 'prop-types';
  4. import React from 'react';
  5. import { defineMessages, injectIntl } from 'react-intl';
  6. import { length } from 'stringz';
  7. import ImmutablePureComponent from 'react-immutable-pure-component';
  8. // Components.
  9. import Button from 'flavours/glitch/components/button';
  10. import Icon from 'flavours/glitch/components/icon';
  11. // Utils.
  12. import { maxChars } from 'flavours/glitch/initial_state';
  13. // Messages.
  14. const messages = defineMessages({
  15. publish: {
  16. defaultMessage: 'Publish',
  17. id: 'compose_form.publish',
  18. },
  19. publishLoud: {
  20. defaultMessage: '{publish}!',
  21. id: 'compose_form.publish_loud',
  22. },
  23. saveChanges: { id: 'compose_form.save_changes', defaultMessage: 'Save changes' },
  24. });
  25. class Publisher extends ImmutablePureComponent {
  26. static propTypes = {
  27. countText: PropTypes.string,
  28. disabled: PropTypes.bool,
  29. intl: PropTypes.object.isRequired,
  30. onSecondarySubmit: PropTypes.func,
  31. onSubmit: PropTypes.func,
  32. privacy: PropTypes.oneOf(['direct', 'private', 'unlisted', 'public']),
  33. sideArm: PropTypes.oneOf(['none', 'direct', 'private', 'unlisted', 'public']),
  34. isEditing: PropTypes.bool,
  35. };
  36. handleSubmit = () => {
  37. this.props.onSubmit();
  38. };
  39. render () {
  40. const { countText, disabled, intl, onSecondarySubmit, privacy, sideArm, isEditing } = this.props;
  41. const diff = maxChars - length(countText || '');
  42. const computedClass = classNames('compose-form__publish', {
  43. disabled: disabled,
  44. over: diff < 0,
  45. });
  46. const privacyIcons = { direct: 'envelope', private: 'lock', public: 'globe', unlisted: 'unlock' };
  47. let publishText;
  48. if (isEditing) {
  49. publishText = intl.formatMessage(messages.saveChanges);
  50. } else if (privacy === 'private' || privacy === 'direct') {
  51. const iconId = privacyIcons[privacy];
  52. publishText = (
  53. <span>
  54. <Icon id={iconId} /> {intl.formatMessage(messages.publish)}
  55. </span>
  56. );
  57. } else {
  58. publishText = privacy !== 'unlisted' ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish);
  59. }
  60. return (
  61. <div className={computedClass}>
  62. {sideArm && !isEditing && sideArm !== 'none' ? (
  63. <div className='compose-form__publish-button-wrapper'>
  64. <Button
  65. className='side_arm'
  66. disabled={disabled}
  67. onClick={onSecondarySubmit}
  68. style={{ padding: null }}
  69. text={<Icon id={privacyIcons[sideArm]} />}
  70. title={`${intl.formatMessage(messages.publish)}: ${intl.formatMessage({ id: `privacy.${sideArm}.short` })}`}
  71. />
  72. </div>
  73. ) : null}
  74. <div className='compose-form__publish-button-wrapper'>
  75. <Button
  76. className='primary'
  77. text={publishText}
  78. title={`${intl.formatMessage(messages.publish)}: ${intl.formatMessage({ id: `privacy.${privacy}.short` })}`}
  79. onClick={this.handleSubmit}
  80. disabled={disabled}
  81. />
  82. </div>
  83. </div>
  84. );
  85. }
  86. }
  87. export default injectIntl(Publisher);