root.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import React from "react"
  2. import AvatarIndex from "misago/components/change-avatar/index"
  3. import AvatarCrop from "misago/components/change-avatar/crop"
  4. import AvatarUpload from "misago/components/change-avatar/upload"
  5. import AvatarGallery from "misago/components/change-avatar/gallery"
  6. import Loader from "misago/components/modal-loader"
  7. import { updateAvatar } from "misago/reducers/users"
  8. import ajax from "misago/services/ajax"
  9. import store from "misago/services/store"
  10. export class ChangeAvatarError extends React.Component {
  11. getErrorReason() {
  12. if (this.props.reason) {
  13. return <p dangerouslySetInnerHTML={{ __html: this.props.reason }} />
  14. } else {
  15. return null
  16. }
  17. }
  18. render() {
  19. return (
  20. <div className="modal-body">
  21. <div className="message-icon">
  22. <span className="material-icon">remove_circle_outline</span>
  23. </div>
  24. <div className="message-body">
  25. <p className="lead">{this.props.message}</p>
  26. {this.getErrorReason()}
  27. <button
  28. className="btn btn-default"
  29. data-dismiss="modal"
  30. type="button"
  31. >
  32. {gettext("Ok")}
  33. </button>
  34. </div>
  35. </div>
  36. )
  37. }
  38. }
  39. export default class extends React.Component {
  40. componentDidMount() {
  41. ajax.get(this.props.user.api.avatar).then(
  42. options => {
  43. this.setState({
  44. component: AvatarIndex,
  45. options: options,
  46. error: null
  47. })
  48. },
  49. rejection => {
  50. this.showError(rejection)
  51. }
  52. )
  53. }
  54. showError = error => {
  55. this.setState({
  56. error
  57. })
  58. }
  59. showIndex = () => {
  60. this.setState({
  61. component: AvatarIndex
  62. })
  63. }
  64. showUpload = () => {
  65. this.setState({
  66. component: AvatarUpload
  67. })
  68. }
  69. showCrop = () => {
  70. this.setState({
  71. component: AvatarCrop
  72. })
  73. }
  74. showGallery = () => {
  75. this.setState({
  76. component: AvatarGallery
  77. })
  78. }
  79. completeFlow = options => {
  80. store.dispatch(updateAvatar(this.props.user, options.avatars))
  81. this.setState({
  82. component: AvatarIndex,
  83. options
  84. })
  85. }
  86. getBody() {
  87. if (this.state) {
  88. if (this.state.error) {
  89. return (
  90. <ChangeAvatarError
  91. message={this.state.error.detail}
  92. reason={this.state.error.reason}
  93. />
  94. )
  95. } else {
  96. return (
  97. <this.state.component
  98. options={this.state.options}
  99. user={this.props.user}
  100. onComplete={this.completeFlow}
  101. showError={this.showError}
  102. showIndex={this.showIndex}
  103. showCrop={this.showCrop}
  104. showUpload={this.showUpload}
  105. showGallery={this.showGallery}
  106. />
  107. )
  108. }
  109. } else {
  110. return <Loader />
  111. }
  112. }
  113. getClassName() {
  114. if (this.state && this.state.error) {
  115. return "modal-dialog modal-message modal-change-avatar"
  116. } else {
  117. return "modal-dialog modal-change-avatar"
  118. }
  119. }
  120. render() {
  121. return (
  122. <div className={this.getClassName()} role="document">
  123. <div className="modal-content">
  124. <div className="modal-header">
  125. <button
  126. type="button"
  127. className="close"
  128. data-dismiss="modal"
  129. aria-label={gettext("Close")}
  130. >
  131. <span aria-hidden="true">&times;</span>
  132. </button>
  133. <h4 className="modal-title">{gettext("Change your avatar")}</h4>
  134. </div>
  135. {this.getBody()}
  136. </div>
  137. </div>
  138. )
  139. }
  140. }
  141. export function select(state) {
  142. return {
  143. user: state.auth.user
  144. }
  145. }