Sunday 3 May 2020

ionic react FileSystem load

snap 2 photos, close app

open camera folder, images are saved

delete pine cone picture 

pine cone picture deleted

open app again, pine cone picture is still loaded
when pictures are taken, they are saved in 2 locations: 
app storage and phone camera folder

open app setting and clear storage

app storage cleaned

open app again, no more picture loaded

open camera folder, locus picture is still on file
//hooks/usePhotoGallery.tsx

import { useState, useEffect } from "react";
import { useCamera } from '@ionic/react-hooks/camera';
import { useFilesystem, base64FromPath } from '@ionic/react-hooks/filesystem';
import { useStorage } from '@ionic/react-hooks/storage';
import { isPlatform } from '@ionic/react';
import {
    CameraResultType, CameraSource, CameraPhoto,
    Capacitor, FilesystemDirectory
} from "@capacitor/core";

export interface Photo {
    filepath: string;
    webviewPath?: string;
    base64?: string;
}

const PHOTO_STORAGE = "photos";

export function usePhotoGallery() {
    const [photos, setPhotos] = useState<Photo[]>([]);
    const { getPhoto } = useCamera();
    const { deleteFile, getUri, readFile, writeFile } = useFilesystem();
    const { get, set } = useStorage();

    //load pictures from app storage when app page opens for one time only
    useEffect(() => {
        const loadSaved = async () => {
            const photosString = await get('photos');
            const photos = (photosString ? JSON.parse(photosString) : []) as Photo[];
            for (let photo of photos) {
                const file = await readFile({
                    path: photo.filepath,
                    directory: FilesystemDirectory.Data
                });
                photo.base64 = `data:image/jpeg;base64,${file.data}`;
            }
            setPhotos(photos);
        };
        loadSaved();
    }, [get, readFile]);

    //save 2 copies of photo, one on app storage, the other on phone camera folder 
    const takePhoto = async () => {
        const cameraPhoto = await getPhoto({
            resultType: CameraResultType.Uri,
            source: CameraSource.Camera,
            quality: 100
        });

        const fileName = new Date().getTime() + '.jpeg';

        const savedFileImage = await savePicture(cameraPhoto, fileName);

        const newPhotos = [savedFileImage, ...photos];
        setPhotos(newPhotos)

        //log app storage path for photos taken
        set(PHOTO_STORAGE, JSON.stringify(newPhotos.map(p => {
            // Don't save the base64 representation of the photo data,
            // since it's already saved on the Filesystem
            const photoCopy = { ...p };
            delete photoCopy.base64;
            return photoCopy;
        })));
    };

    const savePicture = async (photo: CameraPhoto, fileName: string): Promise<Photo> => {
        const base64Data = await base64FromPath(photo.webPath!);
        const savedFile = await writeFile({
            path: fileName,
            data: base64Data,
            directory: FilesystemDirectory.Data
        });

        // Use webPath to display the new image instead of base64 since it's
        // already loaded into memory
        return {
            filepath: fileName,
            webviewPath: photo.webPath
        };
    };

    return {
        photos,
        takePhoto
    };
}

---------------------------------
//tab2.tsx

import React from 'react';
import {
  IonContent, IonHeader, IonPage, IonTitle, IonToolbar, IonButton,
  IonGrid, IonRow, IonCol, IonImg, IonFab, IonFabButton, IonIcon
} from '@ionic/react';
import ExploreContainer from '../components/ExploreContainer';
import './Tab2.css';
import { usePhotoGallery } from '../hooks/usePhotoGallery';
import { camera } from 'ionicons/icons';

const Tab2: React.FC = () => {
  const { photos, takePhoto } = usePhotoGallery();

  return (
    <IonPage>
      <IonHeader>
        <IonToolbar>
          <IonTitle>Camera Example</IonTitle>
        </IonToolbar>
      </IonHeader>
      <IonContent>
        <IonFab vertical='bottom' horizontal='center' slot='fixed'>
          <IonFabButton onClick={() => takePhoto()}>
            <IonIcon icon={camera} />
          </IonFabButton>
        </IonFab>
        <IonGrid>
          <IonRow>
            {photos.map((photo, index) => (
              <IonCol size="6" key={index}>
                <IonImg src={photo.base64 ?? photo.webviewPath} />
              </IonCol>
            ))}
          </IonRow>
        </IonGrid>
      </IonContent>
    </IonPage>
  );
};

export default Tab2;

reference:
https://ionicframework.com/docs/react/your-first-app/4-loading-photos
http://chuanshuoge2.blogspot.com/2020/05/ionic-react-filesystem-save.html

No comments:

Post a Comment