PageStatusAlert.jsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import { withTranslation } from 'react-i18next';
  4. import AppContainer from '../services/AppContainer';
  5. import PageContainer from '../services/PageContainer';
  6. import { createSubscribedElement } from './UnstatedUtils';
  7. /**
  8. *
  9. * @author Yuki Takei <yuki@weseek.co.jp>
  10. *
  11. * @export
  12. * @class PageStatusAlert
  13. * @extends {React.Component}
  14. */
  15. class PageStatusAlert extends React.Component {
  16. constructor(props) {
  17. super(props);
  18. this.state = {
  19. };
  20. this.renderSomeoneEditingAlert = this.renderSomeoneEditingAlert.bind(this);
  21. this.renderDraftExistsAlert = this.renderDraftExistsAlert.bind(this);
  22. this.renderUpdatedAlert = this.renderUpdatedAlert.bind(this);
  23. }
  24. componentWillMount() {
  25. this.props.appContainer.registerComponentInstance('PageStatusAlert', this);
  26. }
  27. refreshPage() {
  28. window.location.reload();
  29. }
  30. renderSomeoneEditingAlert() {
  31. const { t } = this.props;
  32. return (
  33. <div className="alert-hackmd-someone-editing myadmin-alert alert-success myadmin-alert-bottom alertbottom2">
  34. <i className="icon-fw icon-people"></i>
  35. {t('hackmd.someone_editing')}
  36. &nbsp;
  37. <i className="fa fa-angle-double-right"></i>
  38. &nbsp;
  39. <a href="#hackmd">
  40. Open HackMD Editor
  41. </a>
  42. </div>
  43. );
  44. }
  45. renderDraftExistsAlert(isRealtime) {
  46. const { t } = this.props;
  47. return (
  48. <div className="alert-hackmd-draft-exists myadmin-alert alert-success myadmin-alert-bottom alertbottom2">
  49. <i className="icon-fw icon-pencil"></i>
  50. {t('hackmd.this_page_has_draft')}
  51. &nbsp;
  52. <i className="fa fa-angle-double-right"></i>
  53. &nbsp;
  54. <a href="#hackmd">
  55. Open HackMD Editor
  56. </a>
  57. </div>
  58. );
  59. }
  60. renderUpdatedAlert() {
  61. const { t } = this.props;
  62. const label1 = t('edited this page');
  63. const label2 = t('Load latest');
  64. return (
  65. <div className="alert-revision-outdated myadmin-alert alert-warning myadmin-alert-bottom alertbottom2">
  66. <i className="icon-fw icon-bulb"></i>
  67. {this.props.pageContainer.state.lastUpdateUsername} {label1}
  68. &nbsp;
  69. <i className="fa fa-angle-double-right"></i>
  70. &nbsp;
  71. <a href="#" onClick={this.refreshPage}>
  72. {label2}
  73. </a>
  74. </div>
  75. );
  76. }
  77. render() {
  78. let content = <React.Fragment></React.Fragment>;
  79. const {
  80. revisionId, revisionIdHackmdSynced, remoteRevisionId, hasDraftOnHackmd, isHackmdDraftUpdatingInRealtime,
  81. } = this.props.pageContainer.state;
  82. const isRevisionOutdated = revisionId !== remoteRevisionId;
  83. const isHackmdDocumentOutdated = revisionIdHackmdSynced !== remoteRevisionId;
  84. // when remote revision is newer than both
  85. if (isHackmdDocumentOutdated && isRevisionOutdated) {
  86. content = this.renderUpdatedAlert();
  87. }
  88. // when someone editing with HackMD
  89. else if (isHackmdDraftUpdatingInRealtime) {
  90. content = this.renderSomeoneEditingAlert();
  91. }
  92. // when the draft of HackMD is newest
  93. else if (hasDraftOnHackmd) {
  94. content = this.renderDraftExistsAlert();
  95. }
  96. return content;
  97. }
  98. }
  99. /**
  100. * Wrapper component for using unstated
  101. */
  102. const PageStatusAlertWrapper = (props) => {
  103. return createSubscribedElement(PageStatusAlert, props, [AppContainer, PageContainer]);
  104. };
  105. PageStatusAlert.propTypes = {
  106. t: PropTypes.func.isRequired, // i18next
  107. appContainer: PropTypes.instanceOf(AppContainer).isRequired,
  108. pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
  109. };
  110. export default withTranslation()(PageStatusAlertWrapper);