Progress for Release 0.4
Published: 2023-12-05 19:35:25

In my last [post](https://dev.to/mingming-ma/planning-for-release-04-5a4o), I outlined the plans for Release 0.4. Now, I'd like to update on how things are progressing.


1.Directly paste image to attach
Status: Done

Details:
In the `DesktopPromptForm` component, I created a hook of `useEffect` to add/remove the paste event listener to the textarea, as passing the `handlePasteImage` fucntion to `addEventListener` and `removeEventListener` functions.

```ts
  // Attach paste event listener to the textarea
  useEffect(() => {
    const textAreaElement = inputPromptRef.current;
    if (textAreaElement) {
      textAreaElement.addEventListener("paste", handlePasteImage);
    }
    return () => {
      if (textAreaElement) {
        textAreaElement.removeEventListener("paste", handlePasteImage);
      }
    };
    // eslint-disable-next-line
  }, []);
```

In the `handlePasteImage` function, I got the copied files from the `ClipboardEvent.clipboardData`, then filter out not images and null files. Then we can call `setInputImages` function to set the attached images.  

```ts
  const handlePasteImage = (e: ClipboardEvent) => {
    const clipboardData = e.clipboardData;
    const items = Array.from(clipboardData?.items || []);
    const imageFiles = items
      .map((item) => item.getAsFile())
      .filter((file): file is File => file != null && file.type.startsWith("image/"));
    if (imageFiles.length > 0) {
      Promise.all(imageFiles.map((file) => getBase64FromFile(file))).then((base64Strings) => {
        setInputImages((prevImages) => [...prevImages, ...base64Strings]);
      });
    }
  };
```


2.Image in chat messages can be clickable to see full version.
Status: Done

I did this by a using `Modal` component from `@chakra-ui/react`, I included the `Image` within it which accepts the `src` property.

```ts
const ImageModal: React.FC<ImageModalProps> = ({ isOpen, onClose, imageSrc }) => (
  <Modal isOpen={isOpen} onClose={onClose} size="xl" isCentered>
    <ModalOverlay />
    <ModalContent>
      <ModalCloseButton />
      <ModalBody>
        <Image src={imageSrc} alt="Selected Image" maxW="100%" maxH="100vh" m="auto" />
      </ModalBody>
    </ModalContent>
  </Modal>
);
```

Here is the usage 
```ts

import ImageModal from './ImageModal';

const ParentComponent: React.FC = () => {
  const [isOpen, setIsOpen] = useState<boolean>(false);
  const [selectedImage, setSelectedImage] = useState<string>('');

  // Function to open the modal and set the image
  const openModalWithImage = (imageUrl: string) => {
    setSelectedImage(imageUrl);
    setIsOpen(true);
  };

  // Function to close the modal
  const closeModal = () => setIsOpen(false);

  return (
    <div>
      {/* Other component content here */}
      {/* Add Onclick event to the image: <Image onClick={() => openModalWithImage('image-src')}>Open Image</Image> */}

      <ImageModal isOpen={isOpen} onClose={closeModal} imageUrl={selectedImage} />
    </div>
  );
};

export default ParentComponent;
``` 

3.Resize the image in the browser within the max size of the image that OpenAI will process
Status: Skipped 

Reason: `Found Uncaught ReferenceError: process is not defined` error when trying to do `sharp` convert/resize images, guessing it needs server side running so cause this error.


4.Optimize the image locally so upload is faster
Status: Skipped
Reason: Same as above


5.Investigate issue: lot of horizontal scrolling on mobile
Status: Not found the reason yet.

6.Update the icon on mobile to a camera
Status: Done
This is a simple fix, I did by adding a check
```ts
   icon={isMobile ? <BsCamera /> : <BsPaperclip />}
```


7.Support the camera use case, but also attaching a photo from the camera roll
Status: Done

Turned out that we actually do not need the `capture="environment"` in the `input`, without this, we can not only call native camera but also can call Choose File and Photo Library. This is amazing!

```html
     <!-- The hidden file `input` for opening the native camera -->
      <input
        id="cameraFileInput"
        type="file"
        accept="image/*"
// Removed capture="environment"
      />
```
![Camera](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hhn3e74d7hbh5n053ihn.png)