PersonalContainer.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. import { Container } from 'unstated';
  2. import loggerFactory from '@alias/logger';
  3. // eslint-disable-next-line no-unused-vars
  4. const logger = loggerFactory('growi:services:PersonalContainer');
  5. const DEFAULT_IMAGE = '/images/icons/user.svg';
  6. /**
  7. * Service container for personal settings page (PersonalSettings.jsx)
  8. * @extends {Container} unstated Container
  9. */
  10. export default class PersonalContainer extends Container {
  11. constructor(appContainer) {
  12. super();
  13. this.appContainer = appContainer;
  14. this.state = {
  15. retrieveError: null,
  16. name: '',
  17. email: '',
  18. registrationWhiteList: this.appContainer.getConfig().registrationWhiteList,
  19. isEmailPublished: false,
  20. lang: 'en-US',
  21. isGravatarEnabled: false,
  22. isUploadedPicture: false,
  23. uploadedPictureSrc: this.getUploadedPictureSrc(this.appContainer.currentUser),
  24. externalAccounts: [],
  25. isPasswordSet: false,
  26. apiToken: '',
  27. };
  28. }
  29. /**
  30. * Workaround for the mangling in production build to break constructor.name
  31. */
  32. static getClassName() {
  33. return 'PersonalContainer';
  34. }
  35. /**
  36. * retrieve personal data
  37. */
  38. async retrievePersonalData() {
  39. try {
  40. const response = await this.appContainer.apiv3.get('/personal-setting/');
  41. const { currentUser } = response.data;
  42. this.setState({
  43. name: currentUser.name,
  44. email: currentUser.email,
  45. isEmailPublished: currentUser.isEmailPublished,
  46. lang: currentUser.lang,
  47. isGravatarEnabled: currentUser.isGravatarEnabled,
  48. isPasswordSet: (currentUser.password != null),
  49. apiToken: currentUser.apiToken,
  50. });
  51. }
  52. catch (err) {
  53. this.setState({ retrieveError: err });
  54. logger.error(err);
  55. throw new Error('Failed to fetch personal data');
  56. }
  57. }
  58. /**
  59. * define a function for uploaded picture
  60. */
  61. getUploadedPictureSrc(user) {
  62. if (user.image) {
  63. this.setState({ isUploadedPicture: true });
  64. return user.image;
  65. }
  66. if (user.imageAttachment != null) {
  67. this.setState({ isUploadedPicture: true });
  68. return user.imageAttachment.filePathProxied;
  69. }
  70. return DEFAULT_IMAGE;
  71. }
  72. /**
  73. * retrieve external accounts that linked me
  74. */
  75. async retrieveExternalAccounts() {
  76. try {
  77. const response = await this.appContainer.apiv3.get('/personal-setting/external-accounts');
  78. const { externalAccounts } = response.data;
  79. this.setState({ externalAccounts });
  80. }
  81. catch (err) {
  82. this.setState({ retrieveError: err });
  83. logger.error(err);
  84. throw new Error('Failed to fetch external accounts');
  85. }
  86. }
  87. /**
  88. * Change name
  89. */
  90. changeName(inputValue) {
  91. this.setState({ name: inputValue });
  92. }
  93. /**
  94. * Change email
  95. */
  96. changeEmail(inputValue) {
  97. this.setState({ email: inputValue });
  98. }
  99. /**
  100. * Change isEmailPublished
  101. */
  102. changeIsEmailPublished(boolean) {
  103. this.setState({ isEmailPublished: boolean });
  104. }
  105. /**
  106. * Change lang
  107. */
  108. changeLang(lang) {
  109. this.setState({ lang });
  110. }
  111. /**
  112. * Change isGravatarEnabled
  113. */
  114. changeIsGravatarEnabled(boolean) {
  115. this.setState({ isGravatarEnabled: boolean });
  116. }
  117. /**
  118. * Update basic info
  119. * @memberOf PersonalContainer
  120. * @return {Array} basic info
  121. */
  122. async updateBasicInfo() {
  123. try {
  124. const response = await this.appContainer.apiv3.put('/personal-setting/', {
  125. name: this.state.name,
  126. email: this.state.email,
  127. isEmailPublished: this.state.isEmailPublished,
  128. lang: this.state.lang,
  129. });
  130. const { updatedUser } = response.data;
  131. this.setState({
  132. name: updatedUser.name,
  133. email: updatedUser.email,
  134. isEmailPublished: updatedUser.isEmailPublished,
  135. lang: updatedUser.lang,
  136. });
  137. }
  138. catch (err) {
  139. this.setState({ retrieveError: err });
  140. logger.error(err);
  141. throw new Error('Failed to update personal data');
  142. }
  143. }
  144. /**
  145. * Update profile image
  146. * @memberOf PersonalContainer
  147. */
  148. async updateProfileImage() {
  149. try {
  150. const response = await this.appContainer.apiv3.put('/personal-setting/image-type', {
  151. isGravatarEnabled: this.state.isGravatarEnabled,
  152. });
  153. const { userData } = response.data;
  154. this.setState({
  155. isGravatarEnabled: userData.isGravatarEnabled,
  156. });
  157. }
  158. catch (err) {
  159. this.setState({ retrieveError: err });
  160. logger.error(err);
  161. throw new Error('Failed to update profile image');
  162. }
  163. }
  164. /**
  165. * Upload image
  166. */
  167. async uploadAttachment(file) {
  168. try {
  169. const formData = new FormData();
  170. formData.append('file', file);
  171. formData.append('_csrf', this.appContainer.csrfToken);
  172. const response = await this.appContainer.apiPost('/attachments.uploadProfileImage', formData);
  173. this.setState({ isUploadedPicture: true, uploadedPictureSrc: response.attachment.filePathProxied });
  174. }
  175. catch (err) {
  176. this.setState({ retrieveError: err });
  177. logger.error(err);
  178. throw new Error('Failed to upload profile image');
  179. }
  180. }
  181. /**
  182. * Delete image
  183. */
  184. async deleteProfileImage() {
  185. try {
  186. await this.appContainer.apiPost('/attachments.removeProfileImage', { _csrf: this.appContainer.csrfToken });
  187. this.setState({ isUploadedPicture: false, uploadedPictureSrc: DEFAULT_IMAGE });
  188. }
  189. catch (err) {
  190. this.setState({ retrieveError: err });
  191. logger.error(err);
  192. throw new Error('Failed to delete profile image');
  193. }
  194. }
  195. }