Source: input/TakePhotoOqt.js

import React, { createContext, useCallback, useContext, useEffect, useImperativeHandle, useRef, useState } from "react";
import { useCamera } from '@capacitor-community/camera-react/dist';
import { processOptions, FormContext, TakePhotoOqtContext, useVariables, booleanString } from "../..";
import Resizer from "react-image-file-resizer";

/**
 * Componente que renderiza un input para cargar una imagen
 * @name Reactor.Components.Input.TakePhotoOqt
 * @param {string} name name del control
 * @param {string} value valor por defecto
 * @param {JsonString} resizer_options opciones para redimencionar la imagen
 * @param {"true"|"false"} auto_submit determina si al cargar una foto automaticamente se hace submit del form que contiene al control
 * @param {string?} change_var Variable que tomarĂ¡ el valor del control cuando se modifique
 * @param {string} [context = "global"] Contexto donde se encuentra la variable
 * @class 
 * @example 
<form action="MenuPerfilFoto" target="menu">
  <take_photo_oqt name="fotoPerfil" value="" disabled="false" auto_submit="false">
    <take_photo_img_oqt strstyle="object-fit: cover;" alt="img" height="180" width="180" class_name="mx-auto rounded-circle mt-n5 shadow-l" src="{{fotoUsuario}}" />
  </take_photo_oqt>
</form>
 */


export const TakePhotoOqt = React.forwardRef(({name, value, children, not_clear = "false", disabled = "false", auto_submit = "false", resizer_options, change_var, context = "global", ...props }, refTakePhotoOqt) => {
  
  const formContext = useContext(FormContext);
  const variables = useVariables({variable: change_var, context});
  const { getPhoto } = useCamera();
  const ref = useRef();

  const [ state, setState ] = useState({value: value || props.defaultValue, disabled: disabled === "true", auto_submit: auto_submit === "true"})

  useEffect(()=>{
    if(change_var && context){
      if(booleanString(not_clear) && (state.value === null || state.value === undefined)){
        return;
      }
      variables.setData(state.value);
    }
  } , [state.value, change_var, context, not_clear]);

  const resizeImage = (dataUrl) => {
    return new Promise((resolve, reject) => {
      const options = {
        maxWidth: 2000, // Is the maxWidth of the resized new image.
        maxHeight: 2000, // Is the maxHeight of the resized new image.
        compressFormat: "JPEG", // Is the compressFormat of the resized new image.
        quality: 75, // Is the quality of the resized new image.
        rotation: 0, // Is the degree of clockwise rotation to apply to uploaded image.
        outputType: "base64", // Is the output type of the resized new image.
        minWidth: null, // Is the minWidth of the resized new image.
        minHeight: null, // Is the minHeight of the resized new image
        ...processOptions(resizer_options)
      };
      fetch(dataUrl)
        .then(res => res.blob())
        .then(blob => {
          const file = new File([blob], "Image")
          try{
            Resizer.imageFileResizer(
              file,
              options.maxWidth, // Is the maxWidth of the resized new image.
              options.maxHeight, // Is the maxHeight of the resized new image.
              options.compressFormat, // Is the compressFormat of the resized new image.
              options.quality, // Is the quality of the resized new image.
              options.rotation, // Is the degree of clockwise rotation to apply to uploaded image.
              (uri) => {
                resolve(uri);
              },
              options.outputType, // Is the output type of the resized new image.
              options.minWidth, // Is the minWidth of the resized new image.
              options.minHeight // Is the minHeight of the resized new image.*/
            );
          }catch(e){
            console.log(e);
            reject(e);
          }
    
        })
    })
  }

  const triggerCamera = () => {
    if(state.disabled === "true") return;
    getPhoto({
      quality: 100,
      allowEditing: false,
      resultType: "dataUrl"
    }).then((x)=>{

      if(resizer_options){
        resizeImage(x.dataUrl).then(result => {
          setState(state => ({...state, value: result}));
          state.auto_submit && formContext.submit();
        })
      }else{
        setState(state => ({...state, value: x.dataUrl}));
        state.auto_submit && formContext.submit();
      }

    }).catch(e=>{})
  }

  useImperativeHandle(refTakePhotoOqt, () => {
    return {
      triggerCamera: () => {
        triggerCamera();
      }
    };
  }, [triggerCamera]);
  
  return (
    <TakePhotoOqtContext.Provider value={{dataUrl: state.value, disabled: state.disabled, triggerCamera, ok: "true"}}>
      <input 
        ref={ref}
        name={name}
        value={state.value}
        type="hidden"
      />   
      {children} 
    </TakePhotoOqtContext.Provider>
  );
})