Skip to content

Commit 01210dc

Browse files
committed
feat: Add documentation and tutorials for File Picker and In-App Review plugins
1 parent f8536ce commit 01210dc

File tree

7 files changed

+1155
-0
lines changed

7 files changed

+1155
-0
lines changed

src/config/plugins.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ import ShieldExclamationIcon from 'astro-heroicons/mini/ShieldExclamation.astro'
5252
import ArrowsRightLeftIcon from 'astro-heroicons/mini/ArrowsRightLeft.astro'
5353
import FolderIcon from 'astro-heroicons/mini/Folder.astro'
5454
import SunIcon from 'astro-heroicons/mini/Sun.astro'
55+
import StarIcon from 'astro-heroicons/mini/Star.astro'
56+
import FolderOpenIcon from 'astro-heroicons/mini/FolderOpen.astro'
5557

5658
export interface Action {
5759
icon?: any
@@ -819,4 +821,20 @@ export const actions = [
819821
title: 'Keep Awake',
820822
icon: SunIcon,
821823
},
824+
{
825+
name: '@capgo/capacitor-in-app-review',
826+
author: 'github.com/Cap-go',
827+
description: 'Prompt users to submit app store ratings and reviews without leaving your app using native iOS and Android APIs',
828+
href: 'https://github.com/Cap-go/capacitor-in-app-review/',
829+
title: 'In App Review',
830+
icon: StarIcon,
831+
},
832+
{
833+
name: '@capgo/capacitor-file-picker',
834+
author: 'github.com/Cap-go',
835+
description: 'Pick files, images, videos, and directories with full native support for iOS and Android including HEIC conversion',
836+
href: 'https://github.com/Cap-go/capacitor-file-picker/',
837+
title: 'File Picker',
838+
icon: FolderOpenIcon,
839+
},
822840
]
Lines changed: 355 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,355 @@
1+
---
2+
title: Getting Started
3+
description: Learn how to install and use the File Picker plugin to select files, images, videos, and directories in your Capacitor app.
4+
sidebar:
5+
order: 2
6+
---
7+
8+
import { Tabs, TabItem } from '@astrojs/starlight/components';
9+
import { Code, Steps } from '@astrojs/starlight/components';
10+
import { PackageManagers } from 'starlight-package-managers'
11+
12+
<Steps>
13+
1. **Install the package**
14+
<PackageManagers pkg="@capgo/capacitor-file-picker" pkgManagers={['npm', 'pnpm', 'yarn', 'bun']} />
15+
16+
2. **Sync with native projects**
17+
<PackageManagers type="exec" pkg="cap" args="sync" pkgManagers={['npm', 'pnpm', 'yarn', 'bun']} />
18+
</Steps>
19+
20+
## Requirements
21+
22+
- iOS: iOS 15.0+
23+
- Android: API 24+ (Android 7.0+)
24+
- Web: Modern browsers with File API support
25+
26+
## Basic Usage
27+
28+
### Pick Files
29+
30+
```typescript
31+
import { FilePicker } from '@capgo/capacitor-file-picker';
32+
33+
// Pick any files
34+
const pickFiles = async () => {
35+
const result = await FilePicker.pickFiles({
36+
limit: 5 // Max 5 files
37+
});
38+
39+
for (const file of result.files) {
40+
console.log('File name:', file.name);
41+
console.log('File path:', file.path);
42+
console.log('MIME type:', file.mimeType);
43+
console.log('Size:', file.size);
44+
}
45+
};
46+
47+
// Pick specific file types
48+
const pickPDFs = async () => {
49+
const result = await FilePicker.pickFiles({
50+
types: ['application/pdf'],
51+
limit: 1
52+
});
53+
return result.files[0];
54+
};
55+
```
56+
57+
### Pick Images
58+
59+
```typescript
60+
import { FilePicker } from '@capgo/capacitor-file-picker';
61+
62+
const pickImages = async () => {
63+
const result = await FilePicker.pickImages({
64+
limit: 10,
65+
ordered: true // Show selection order badges (iOS 15+)
66+
});
67+
68+
for (const image of result.files) {
69+
console.log('Image:', image.name);
70+
console.log('Dimensions:', image.width, 'x', image.height);
71+
console.log('Path:', image.path);
72+
}
73+
};
74+
```
75+
76+
### Pick Videos
77+
78+
```typescript
79+
import { FilePicker } from '@capgo/capacitor-file-picker';
80+
81+
const pickVideos = async () => {
82+
const result = await FilePicker.pickVideos({
83+
limit: 3,
84+
skipTranscoding: true // Skip video transcoding on iOS
85+
});
86+
87+
for (const video of result.files) {
88+
console.log('Video:', video.name);
89+
console.log('Duration:', video.duration, 'seconds');
90+
console.log('Dimensions:', video.width, 'x', video.height);
91+
}
92+
};
93+
```
94+
95+
### Pick Media (Images + Videos)
96+
97+
```typescript
98+
import { FilePicker } from '@capgo/capacitor-file-picker';
99+
100+
const pickMedia = async () => {
101+
const result = await FilePicker.pickMedia({
102+
limit: 0 // Unlimited selection
103+
});
104+
105+
return result.files;
106+
};
107+
```
108+
109+
### Pick Directory
110+
111+
```typescript
112+
import { FilePicker } from '@capgo/capacitor-file-picker';
113+
114+
const pickDirectory = async () => {
115+
const result = await FilePicker.pickDirectory();
116+
console.log('Selected directory:', result.path);
117+
return result.path;
118+
};
119+
```
120+
121+
## API Reference
122+
123+
### pickFiles(options?)
124+
125+
Pick one or more files from the device.
126+
127+
```typescript
128+
interface PickFilesOptions {
129+
types?: string[]; // MIME types or extensions: ['image/*'], ['application/pdf']
130+
limit?: number; // Max files (0 = unlimited)
131+
readData?: boolean; // Return base64 data
132+
}
133+
134+
const result = await FilePicker.pickFiles(options);
135+
// Returns: { files: PickedFile[] }
136+
```
137+
138+
### pickImages(options?)
139+
140+
Pick images from the gallery. Android/iOS only.
141+
142+
```typescript
143+
interface PickMediaOptions {
144+
limit?: number; // Max files (0 = unlimited)
145+
readData?: boolean; // Return base64 data
146+
skipTranscoding?: boolean; // iOS: Skip transcoding
147+
ordered?: boolean; // iOS 15+: Show selection order
148+
}
149+
150+
const result = await FilePicker.pickImages(options);
151+
```
152+
153+
### pickVideos(options?)
154+
155+
Pick videos from the gallery. Android/iOS only.
156+
157+
```typescript
158+
const result = await FilePicker.pickVideos(options);
159+
```
160+
161+
### pickMedia(options?)
162+
163+
Pick images or videos from the gallery. Android/iOS only.
164+
165+
```typescript
166+
const result = await FilePicker.pickMedia(options);
167+
```
168+
169+
### pickDirectory()
170+
171+
Pick a directory. Android/iOS only.
172+
173+
```typescript
174+
const result = await FilePicker.pickDirectory();
175+
// Returns: { path: string }
176+
```
177+
178+
### convertHeicToJpeg(options)
179+
180+
Convert a HEIC image to JPEG. iOS only.
181+
182+
```typescript
183+
interface ConvertHeicToJpegOptions {
184+
path: string; // Path to HEIC file
185+
quality?: number; // 0.0 - 1.0 (default: 0.9)
186+
}
187+
188+
const result = await FilePicker.convertHeicToJpeg({
189+
path: '/path/to/image.heic',
190+
quality: 0.8
191+
});
192+
// Returns: { path: string } - Path to converted JPEG
193+
```
194+
195+
### copyFile(options)
196+
197+
Copy a file to a new location.
198+
199+
```typescript
200+
interface CopyFileOptions {
201+
from: string; // Source path
202+
to: string; // Destination path
203+
overwrite?: boolean; // Overwrite if exists (default: false)
204+
}
205+
206+
await FilePicker.copyFile({
207+
from: '/path/to/source.jpg',
208+
to: '/path/to/destination.jpg',
209+
overwrite: true
210+
});
211+
```
212+
213+
### checkPermissions() / requestPermissions()
214+
215+
Check or request file access permissions. Android only.
216+
217+
```typescript
218+
const status = await FilePicker.checkPermissions();
219+
// Returns: { readExternalStorage: 'granted' | 'denied' | 'prompt' }
220+
221+
const newStatus = await FilePicker.requestPermissions();
222+
```
223+
224+
## PickedFile Interface
225+
226+
```typescript
227+
interface PickedFile {
228+
name: string; // File name
229+
path: string; // File path
230+
mimeType: string; // MIME type
231+
size: number; // Size in bytes
232+
data?: string; // Base64 data (if readData was true)
233+
blob?: Blob; // Blob instance (Web only)
234+
width?: number; // Width in pixels (images/videos)
235+
height?: number; // Height in pixels (images/videos)
236+
duration?: number; // Duration in seconds (videos)
237+
modifiedAt?: number; // Last modified timestamp
238+
}
239+
```
240+
241+
## Complete Example
242+
243+
```typescript
244+
import { FilePicker } from '@capgo/capacitor-file-picker';
245+
import { Capacitor } from '@capacitor/core';
246+
247+
export class FilePickerService {
248+
async pickProfileImage(): Promise<string | null> {
249+
try {
250+
const result = await FilePicker.pickImages({
251+
limit: 1
252+
});
253+
254+
if (result.files.length === 0) {
255+
return null;
256+
}
257+
258+
const file = result.files[0];
259+
260+
// Convert HEIC to JPEG on iOS if needed
261+
if (Capacitor.getPlatform() === 'ios' &&
262+
file.mimeType === 'image/heic') {
263+
const converted = await FilePicker.convertHeicToJpeg({
264+
path: file.path,
265+
quality: 0.9
266+
});
267+
return converted.path;
268+
}
269+
270+
return file.path;
271+
} catch (error) {
272+
console.error('Failed to pick image:', error);
273+
return null;
274+
}
275+
}
276+
277+
async pickDocuments(): Promise<PickedFile[]> {
278+
const result = await FilePicker.pickFiles({
279+
types: [
280+
'application/pdf',
281+
'application/msword',
282+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
283+
],
284+
limit: 10
285+
});
286+
287+
return result.files;
288+
}
289+
290+
async pickAndReadFile(): Promise<{ name: string; data: string } | null> {
291+
const result = await FilePicker.pickFiles({
292+
limit: 1,
293+
readData: true
294+
});
295+
296+
if (result.files.length === 0) return null;
297+
298+
const file = result.files[0];
299+
return {
300+
name: file.name,
301+
data: file.data! // Base64 encoded data
302+
};
303+
}
304+
305+
async getVideoForUpload(): Promise<{
306+
path: string;
307+
duration: number;
308+
dimensions: { width: number; height: number };
309+
} | null> {
310+
const result = await FilePicker.pickVideos({
311+
limit: 1,
312+
skipTranscoding: false // Ensure compatible format
313+
});
314+
315+
if (result.files.length === 0) return null;
316+
317+
const video = result.files[0];
318+
return {
319+
path: video.path,
320+
duration: video.duration || 0,
321+
dimensions: {
322+
width: video.width || 0,
323+
height: video.height || 0
324+
}
325+
};
326+
}
327+
}
328+
```
329+
330+
## Platform Notes
331+
332+
### iOS
333+
334+
- Requires iOS 15.0+
335+
- Uses `PHPickerViewController` for images/videos
336+
- Uses `UIDocumentPickerViewController` for files
337+
- HEIC images can be converted to JPEG using `convertHeicToJpeg()`
338+
- `ordered` option shows selection order badges (iOS 15+)
339+
- `skipTranscoding` prevents automatic video format conversion
340+
341+
### Android
342+
343+
- Requires API 24+ (Android 7.0+)
344+
- Uses `Intent.ACTION_OPEN_DOCUMENT` for file picking
345+
- Uses `Intent.ACTION_PICK` with MediaStore for media
346+
- Permissions are automatically requested when needed
347+
- Check permissions with `checkPermissions()` before picking
348+
349+
### Web
350+
351+
- Uses native `<input type="file">` element
352+
- Returns `Blob` objects in the `blob` property
353+
- `pickDirectory()` is not supported on web
354+
- HEIC conversion is not supported on web
355+
- Some metadata (dimensions, duration) may not be available

0 commit comments

Comments
 (0)