snap 2 photos
press first photo, press delete on the bottom action sheet
close app and open app again, first photo is permanently deleted
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();
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]);
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)
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
};
};
//delete photo from app storage, update photo array record
const deletePhoto = async (photo: Photo) => {
// Remove this photo from the Photos reference data array
const newPhotos = photos.filter(p => p.filepath !== photo.filepath);
// Update photos array cache by overwriting the existing photo array
set(PHOTO_STORAGE, JSON.stringify(newPhotos));
// delete photo file from filesystem
//find file name after directory path
const filename = photo.filepath.substr(photo.filepath.lastIndexOf('/') + 1);
await deleteFile({
path: filename,
directory: FilesystemDirectory.Data
});
setPhotos(newPhotos);
};
return {
photos,
takePhoto,
deletePhoto
};
}
----------------------------------
//pages/tab2.tsx
import React, { useState } from 'react';
import {
IonContent, IonHeader, IonPage, IonTitle, IonToolbar, IonButton,
IonGrid, IonRow, IonCol, IonImg, IonFab, IonFabButton, IonIcon,
IonActionSheet
} from '@ionic/react';
import ExploreContainer from '../components/ExploreContainer';
import './Tab2.css';
import { usePhotoGallery, Photo } from '../hooks/usePhotoGallery';
import { camera, trash, close } from 'ionicons/icons';
const Tab2: React.FC = () => {
const { photos, takePhoto, deletePhoto } = usePhotoGallery();
const [photoToDelete, setPhotoToDelete] = useState<Photo>();
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 onClick={() => setPhotoToDelete(photo)}
src={photo.base64 ?? photo.webviewPath} />
</IonCol>
))}
</IonRow>
</IonGrid>
<IonActionSheet
isOpen={!!photoToDelete}
buttons={[{
text: 'Delete',
role: 'destructive',
icon: trash,
cssClass: 'danger-action',
handler: () => {
if (photoToDelete) {
deletePhoto(photoToDelete);
setPhotoToDelete(undefined);
}
}
}, {
text: 'Cancel',
icon: close,
role: 'cancel'
}]}
onDidDismiss={() => setPhotoToDelete(undefined)}
/>
</IonContent>
</IonPage>
);
};
export default Tab2;
------------------------------
//pages/tab2.css
.danger-action {
--color: red !important;
--button-color: red !important;
}
reference:
https://ionicframework.com/docs/react/your-first-app/7-live-reload
https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_lastindexof
https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_substr
actionsheet button color
https://stackoverflow.com/questions/44129065/how-to-change-the-color-of-custom-icons-in-an-action-sheet-ionic
https://github.com/ionic-team/ionic/issues/17300
No comments:
Post a Comment