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.

UploadImageButton.js 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // @flow
  2. import React, { useCallback, useRef } from 'react';
  3. import uuid from 'uuid';
  4. import { translate } from '../../base/i18n';
  5. import { Icon, IconPlusCircle } from '../../base/icons';
  6. import { VIRTUAL_BACKGROUND_TYPE, type Image } from '../constants';
  7. import { resizeImage } from '../functions';
  8. import logger from '../logger';
  9. type Props = {
  10. /**
  11. * Callback used to set the 'loading' state of the parent component.
  12. */
  13. setLoading: Function,
  14. /**
  15. * Callback used to set the options.
  16. */
  17. setOptions: Function,
  18. /**
  19. * Callback used to set the storedImages array.
  20. */
  21. setStoredImages: Function,
  22. /**
  23. * A list of images locally stored.
  24. */
  25. storedImages: Array<Image>,
  26. /**
  27. * If a label should be displayed alongside the button.
  28. */
  29. showLabel: boolean,
  30. /**
  31. * Used for translation.
  32. */
  33. t: Function
  34. }
  35. /**
  36. * Component used to upload an image.
  37. *
  38. * @param {Object} Props - The props of the component.
  39. * @returns {React$Node}
  40. */
  41. function UploadImageButton({
  42. setLoading,
  43. setOptions,
  44. setStoredImages,
  45. showLabel,
  46. storedImages,
  47. t
  48. }: Props) {
  49. const uploadImageButton: Object = useRef(null);
  50. const uploadImageKeyPress = useCallback(e => {
  51. if (uploadImageButton.current && (e.key === ' ' || e.key === 'Enter')) {
  52. e.preventDefault();
  53. uploadImageButton.current.click();
  54. }
  55. }, [ uploadImageButton.current ]);
  56. const uploadImage = useCallback(async e => {
  57. const reader = new FileReader();
  58. const imageFile = e.target.files;
  59. reader.readAsDataURL(imageFile[0]);
  60. reader.onload = async () => {
  61. const url = await resizeImage(reader.result);
  62. const uuId = uuid.v4();
  63. setStoredImages([
  64. ...storedImages,
  65. {
  66. id: uuId,
  67. src: url
  68. }
  69. ]);
  70. setOptions({
  71. backgroundType: VIRTUAL_BACKGROUND_TYPE.IMAGE,
  72. enabled: true,
  73. url,
  74. selectedThumbnail: uuId
  75. });
  76. };
  77. logger.info('New virtual background image uploaded!');
  78. reader.onerror = () => {
  79. setLoading(false);
  80. logger.error('Failed to upload virtual image!');
  81. };
  82. }, [ storedImages ]);
  83. return (
  84. <>
  85. {showLabel && <label
  86. aria-label = { t('virtualBackground.uploadImage') }
  87. className = 'file-upload-label'
  88. htmlFor = 'file-upload'
  89. onKeyPress = { uploadImageKeyPress }
  90. tabIndex = { 0 } >
  91. <Icon
  92. className = { 'add-background' }
  93. size = { 20 }
  94. src = { IconPlusCircle } />
  95. {t('virtualBackground.addBackground')}
  96. </label>}
  97. <input
  98. accept = 'image/*'
  99. className = 'file-upload-btn'
  100. id = 'file-upload'
  101. onChange = { uploadImage }
  102. ref = { uploadImageButton }
  103. type = 'file' />
  104. </>
  105. );
  106. }
  107. export default translate(UploadImageButton);