Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

UploadImageButton.tsx 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import React, { useCallback, useRef } from 'react';
  2. import { WithTranslation } from 'react-i18next';
  3. import { makeStyles } from 'tss-react/mui';
  4. import { v4 as uuidv4 } from 'uuid';
  5. import { translate } from '../../base/i18n/functions';
  6. import Icon from '../../base/icons/components/Icon';
  7. import { IconPlus } from '../../base/icons/svg';
  8. import { type Image, VIRTUAL_BACKGROUND_TYPE } from '../constants';
  9. import { resizeImage } from '../functions';
  10. import logger from '../logger';
  11. interface IProps extends WithTranslation {
  12. /**
  13. * Callback used to set the 'loading' state of the parent component.
  14. */
  15. setLoading: Function;
  16. /**
  17. * Callback used to set the options.
  18. */
  19. setOptions: Function;
  20. /**
  21. * Callback used to set the storedImages array.
  22. */
  23. setStoredImages: Function;
  24. /**
  25. * If a label should be displayed alongside the button.
  26. */
  27. showLabel: boolean;
  28. /**
  29. * A list of images locally stored.
  30. */
  31. storedImages: Array<Image>;
  32. }
  33. const useStyles = makeStyles()(theme => {
  34. return {
  35. addBackground: {
  36. marginRight: theme.spacing(2)
  37. },
  38. button: {
  39. display: 'none'
  40. },
  41. label: {
  42. fontSize: '14px',
  43. fontWeight: 600,
  44. lineHeight: '20px',
  45. marginTop: theme.spacing(3),
  46. marginBottom: theme.spacing(2),
  47. color: '#669aec',
  48. display: 'inline-flex',
  49. cursor: 'pointer'
  50. }
  51. };
  52. });
  53. /**
  54. * Component used to upload an image.
  55. *
  56. * @param {Object} Props - The props of the component.
  57. * @returns {React$Node}
  58. */
  59. function UploadImageButton({
  60. setLoading,
  61. setOptions,
  62. setStoredImages,
  63. showLabel,
  64. storedImages,
  65. t
  66. }: IProps) {
  67. const { classes } = useStyles();
  68. const uploadImageButton = useRef<HTMLInputElement>(null);
  69. const uploadImageKeyPress = useCallback(e => {
  70. if (uploadImageButton.current && (e.key === ' ' || e.key === 'Enter')) {
  71. e.preventDefault();
  72. uploadImageButton.current.click();
  73. }
  74. }, [ uploadImageButton.current ]);
  75. const uploadImage = useCallback(async e => {
  76. const reader = new FileReader();
  77. const imageFile = e.target.files;
  78. reader.readAsDataURL(imageFile[0]);
  79. reader.onload = async () => {
  80. const url = await resizeImage(reader.result);
  81. const uuId = uuidv4();
  82. setStoredImages([
  83. ...storedImages,
  84. {
  85. id: uuId,
  86. src: url
  87. }
  88. ]);
  89. setOptions({
  90. backgroundType: VIRTUAL_BACKGROUND_TYPE.IMAGE,
  91. enabled: true,
  92. url,
  93. selectedThumbnail: uuId
  94. });
  95. };
  96. logger.info('New virtual background image uploaded!');
  97. reader.onerror = () => {
  98. setLoading(false);
  99. logger.error('Failed to upload virtual image!');
  100. };
  101. }, [ storedImages ]);
  102. return (
  103. <>
  104. {showLabel && <label
  105. aria-label = { t('virtualBackground.uploadImage') }
  106. className = { classes.label }
  107. htmlFor = 'file-upload'
  108. onKeyPress = { uploadImageKeyPress }
  109. tabIndex = { 0 } >
  110. <Icon
  111. className = { classes.addBackground }
  112. size = { 20 }
  113. src = { IconPlus } />
  114. {t('virtualBackground.addBackground')}
  115. </label>}
  116. <input
  117. accept = 'image/*'
  118. className = { classes.button }
  119. id = 'file-upload'
  120. onChange = { uploadImage }
  121. ref = { uploadImageButton }
  122. type = 'file' />
  123. </>
  124. );
  125. }
  126. export default translate(UploadImageButton);