PageStatusAlert.jsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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(this);
  26. }
  27. refreshPage() {
  28. window.location.reload();
  29. }
  30. renderSomeoneEditingAlert() {
  31. return (
  32. <div className="alert-hackmd-someone-editing myadmin-alert alert-success myadmin-alert-bottom alertbottom2">
  33. <i className="icon-fw icon-people"></i>
  34. Someone editing this page on HackMD
  35. &nbsp;
  36. <i className="fa fa-angle-double-right"></i>
  37. &nbsp;
  38. <a href="#hackmd">
  39. Open HackMD Editor
  40. </a>
  41. </div>
  42. );
  43. }
  44. renderDraftExistsAlert(isRealtime) {
  45. return (
  46. <div className="alert-hackmd-draft-exists myadmin-alert alert-success myadmin-alert-bottom alertbottom2">
  47. <i className="icon-fw icon-pencil"></i>
  48. This page has a draft on HackMD
  49. &nbsp;
  50. <i className="fa fa-angle-double-right"></i>
  51. &nbsp;
  52. <a href="#hackmd">
  53. Open HackMD Editor
  54. </a>
  55. </div>
  56. );
  57. }
  58. renderUpdatedAlert() {
  59. const { t } = this.props;
  60. const label1 = t('edited this page');
  61. const label2 = t('Load latest');
  62. return (
  63. <div className="alert-revision-outdated myadmin-alert alert-warning myadmin-alert-bottom alertbottom2">
  64. <i className="icon-fw icon-bulb"></i>
  65. {this.props.pageContainer.state.lastUpdateUsername} {label1}
  66. &nbsp;
  67. <i className="fa fa-angle-double-right"></i>
  68. &nbsp;
  69. <a onClick={this.refreshPage}>
  70. {label2}
  71. </a>
  72. </div>
  73. );
  74. }
  75. render() {
  76. let content = <React.Fragment></React.Fragment>;
  77. const {
  78. revisionId, revisionIdHackmdSynced, remoteRevisionId, hasDraftOnHackmd, isHackmdDraftUpdatingInRealtime,
  79. } = this.props.pageContainer.state;
  80. const isRevisionOutdated = revisionId !== remoteRevisionId;
  81. const isHackmdDocumentOutdated = revisionIdHackmdSynced !== remoteRevisionId;
  82. // when remote revision is newer than both
  83. if (isHackmdDocumentOutdated && isRevisionOutdated) {
  84. content = this.renderUpdatedAlert();
  85. }
  86. // when someone editing with HackMD
  87. else if (isHackmdDraftUpdatingInRealtime) {
  88. content = this.renderSomeoneEditingAlert();
  89. }
  90. // when the draft of HackMD is newest
  91. else if (hasDraftOnHackmd) {
  92. content = this.renderDraftExistsAlert();
  93. }
  94. return content;
  95. }
  96. }
  97. /**
  98. * Wrapper component for using unstated
  99. */
  100. const PageStatusAlertWrapper = (props) => {
  101. return createSubscribedElement(PageStatusAlert, props, [AppContainer, PageContainer]);
  102. };
  103. PageStatusAlert.propTypes = {
  104. t: PropTypes.func.isRequired, // i18next
  105. appContainer: PropTypes.instanceOf(AppContainer).isRequired,
  106. pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
  107. };
  108. export default withTranslation()(PageStatusAlertWrapper);