Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

UploadImageButton.tsx 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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. '& svg': {
  38. fill: '#669aec !important'
  39. }
  40. },
  41. button: {
  42. display: 'none'
  43. },
  44. label: {
  45. fontSize: '14px',
  46. fontWeight: 600,
  47. lineHeight: '20px',
  48. marginTop: theme.spacing(3),
  49. marginBottom: theme.spacing(2),
  50. color: '#669aec',
  51. display: 'inline-flex',
  52. cursor: 'pointer'
  53. }
  54. };
  55. });
  56. /**
  57. * Component used to upload an image.
  58. *
  59. * @param {Object} Props - The props of the component.
  60. * @returns {React$Node}
  61. */
  62. function UploadImageButton({
  63. setLoading,
  64. setOptions,
  65. setStoredImages,
  66. showLabel,
  67. storedImages,
  68. t
  69. }: IProps) {
  70. const { classes } = useStyles();
  71. const uploadImageButton = useRef<HTMLInputElement>(null);
  72. const uploadImageKeyPress = useCallback(e => {
  73. if (uploadImageButton.current && (e.key === ' ' || e.key === 'Enter')) {
  74. e.preventDefault();
  75. uploadImageButton.current.click();
  76. }
  77. }, [ uploadImageButton.current ]);
  78. const uploadImage = useCallback(async e => {
  79. const reader = new FileReader();
  80. const imageFile = e.target.files;
  81. reader.readAsDataURL(imageFile[0]);
  82. reader.onload = async () => {
  83. const url = await resizeImage(reader.result);
  84. const uuId = uuidv4();
  85. setStoredImages([
  86. ...storedImages,
  87. {
  88. id: uuId,
  89. src: url
  90. }
  91. ]);
  92. setOptions({
  93. backgroundType: VIRTUAL_BACKGROUND_TYPE.IMAGE,
  94. enabled: true,
  95. url,
  96. selectedThumbnail: uuId
  97. });
  98. };
  99. logger.info('New virtual background image uploaded!');
  100. reader.onerror = () => {
  101. setLoading(false);
  102. logger.error('Failed to upload virtual image!');
  103. };
  104. }, [ storedImages ]);
  105. return (
  106. <>
  107. {showLabel && <label
  108. aria-label = { t('virtualBackground.uploadImage') }
  109. className = { classes.label }
  110. htmlFor = 'file-upload'
  111. onKeyPress = { uploadImageKeyPress }
  112. tabIndex = { 0 } >
  113. <Icon
  114. className = { classes.addBackground }
  115. size = { 20 }
  116. src = { IconPlus } />
  117. {t('virtualBackground.addBackground')}
  118. </label>}
  119. <input
  120. accept = 'image/*'
  121. className = { classes.button }
  122. id = 'file-upload'
  123. onChange = { uploadImage }
  124. ref = { uploadImageButton }
  125. type = 'file' />
  126. </>
  127. );
  128. }
  129. export default translate(UploadImageButton);