-
-
Notifications
You must be signed in to change notification settings - Fork 51
Expand file tree
/
Copy pathusePhotoGallery.ts
More file actions
126 lines (108 loc) · 3.49 KB
/
usePhotoGallery.ts
File metadata and controls
126 lines (108 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { Capacitor } from '@capacitor/core'
import type { Photo } from '@capacitor/camera'
import { Camera, CameraSource, CameraResultType } from '@capacitor/camera'
import { Filesystem, Directory } from '@capacitor/filesystem'
import { Preferences } from '@capacitor/preferences'
export const usePhotoGallery = () => {
const photos = ref<UserPhoto[]>([])
const PHOTO_STORAGE = 'photos'
const loadSaved = async () => {
const photoList = await Preferences.get({ key: PHOTO_STORAGE })
const photosInStorage = photoList.value ? JSON.parse(photoList.value) : []
// If running on the web...
if (!isPlatform('hybrid')) {
for (const photo of photosInStorage) {
const file = await Filesystem.readFile({
path: photo.filepath,
directory: Directory.Data,
})
// Web platform only: Load the photo as base64 data
photo.webviewPath = `data:image/jpeg;base64,${file.data}`
}
}
photos.value = photosInStorage
}
const convertBlobToBase64 = (blob: Blob) =>
new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onerror = reject
reader.onload = () => {
resolve(reader.result)
}
reader.readAsDataURL(blob)
})
const savePicture = async (photo: Photo, fileName: string): Promise<UserPhoto> => {
let base64Data: string | Blob
// "hybrid" will detect Cordova or Capacitor;
if (isPlatform('hybrid')) {
const file = await Filesystem.readFile({
path: photo.path!,
})
base64Data = file.data
}
else {
// Fetch the photo, read as a blob, then convert to base64 format
const response = await fetch(photo.webPath!)
const blob = await response.blob()
base64Data = (await convertBlobToBase64(blob)) as string
}
const savedFile = await Filesystem.writeFile({
path: fileName,
data: base64Data,
directory: Directory.Data,
})
if (isPlatform('hybrid')) {
// Display the new image by rewriting the 'file://' path to HTTP
// Details: https://ionicframework.com/docs/building/webview#file-protocol
return {
filepath: savedFile.uri,
webviewPath: Capacitor.convertFileSrc(savedFile.uri),
}
}
else {
// Use webPath to display the new image instead of base64 since it's
// already loaded into memory
return {
filepath: fileName,
webviewPath: photo.webPath,
}
}
}
const takePhoto = async () => {
const photo = await Camera.getPhoto({
resultType: CameraResultType.Uri,
source: CameraSource.Camera,
quality: 100,
})
const fileName = new Date().getTime() + '.jpeg'
const savedFileImage = await savePicture(photo, fileName)
photos.value = [savedFileImage, ...photos.value]
}
const deletePhoto = async (photo: UserPhoto) => {
// Remove this photo from the Photos reference data array
photos.value = photos.value.filter(p => p.filepath !== photo.filepath)
// delete photo file from filesystem
const filename = photo.filepath.substr(photo.filepath.lastIndexOf('/') + 1)
await Filesystem.deleteFile({
path: filename,
directory: Directory.Data,
})
}
const cachePhotos = () => {
Preferences.set({
key: PHOTO_STORAGE,
value: JSON.stringify(photos.value),
})
}
onMounted(loadSaved)
watch(photos, cachePhotos)
return {
photos,
takePhoto,
deletePhoto,
}
}
export interface UserPhoto {
filepath: string
webviewPath?: string
}