Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
69cdaf6
feat: add web implementation for takePhoto and chooseFromGallery
alexgerardojacinto Mar 23, 2026
fda773f
Merge branch 'feat/RMET-4099/camera-unification' into feat/RMET-5029/…
OS-pedrogustavobilro Mar 24, 2026
6f2504b
feat: get resolution for images and videos
alexgerardojacinto Mar 24, 2026
ce960fe
refactor: remove redundant assign
alexgerardojacinto Mar 24, 2026
96e5abf
fix: use rear camera as default
alexgerardojacinto Mar 24, 2026
a05e1df
feat: add size, creationDate, and duration to new Web functions
alexgerardojacinto Mar 24, 2026
ebdf7ae
fix: remove limit parameter from Web
alexgerardojacinto Mar 24, 2026
8db1dbd
fix: add thumbnail to chooseFromGallery, for both images and videos
alexgerardojacinto Mar 24, 2026
99f89c5
refactor: remove duplicated code
alexgerardojacinto Mar 24, 2026
5463939
feat: use includeMetadata for takePhoto and chooseFromGallery on Web
alexgerardojacinto Mar 24, 2026
db31e98
fix: show photos on older methods when resultType base64 or dataUrl
OS-ruimoreiramendes Mar 24, 2026
8b0f1c5
refactor: avoid code duplication and improve event listeners
alexgerardojacinto Mar 24, 2026
0f4c9f3
chore(android): update Android bridge with new lib version
alexgerardojacinto Mar 24, 2026
d0d2a6f
chore: remove redundant doc
alexgerardojacinto Mar 25, 2026
6573fec
chore: update docs
alexgerardojacinto Mar 25, 2026
2ca8617
chore: update docs
alexgerardojacinto Mar 25, 2026
aeaadff
chore: update src/definitions.ts
alexgerardojacinto Mar 25, 2026
8998b2c
refactor: make Photo.saved optional like other parameters (e.g. exif)
alexgerardojacinto Mar 25, 2026
8e3f565
refactor: make MediaMetadata.resolution optional
alexgerardojacinto Mar 25, 2026
92ede10
refactor: remove duplicated code
alexgerardojacinto Mar 25, 2026
6772ebc
refactor: avoid returning 0 resolution
alexgerardojacinto Mar 25, 2026
2e37fc9
fix: always return video thumbnail
alexgerardojacinto Mar 25, 2026
17525f6
fix: remove resolution from if condition
alexgerardojacinto Mar 25, 2026
02bd832
chore: run prettier to fix lint issues
alexgerardojacinto Mar 25, 2026
404acce
fix: revert previous commit and keep Photo API as it was
alexgerardojacinto Mar 25, 2026
c2e8dd1
test: test commit
alexgerardojacinto Mar 25, 2026
caeff57
chore(example-app): Remove `webUseInput` for chooseFromGallery
OS-pedrogustavobilro Mar 26, 2026
dac03f1
chore(example-app): Minor notice for MediaHistoryPage in PWA
OS-pedrogustavobilro Mar 26, 2026
933a66a
chore(example-app): Show thumbnail from plugin on video
OS-pedrogustavobilro Mar 26, 2026
09f2bd4
Revert "test: test commit"
alexgerardojacinto Mar 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 23 additions & 23 deletions README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -832,9 +832,6 @@ class IonCameraFlow(
activity,
intent,
ionParams,
{ image ->
//TODO remove this callback
},
{ mediaResult ->
handleMediaResult(mediaResult)
},
Expand Down Expand Up @@ -938,7 +935,6 @@ class IonCameraFlow(
correctOrientation = correctOrientation,
saveToPhotoAlbum = saveToGallery,
includeMetadata = includeMetadata,
latestVersion = true //TODO check this, because now we don't have resultType in the new Api
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ class ChooseFromGalleryConfigurable extends React.Component<
targetWidth: config.targetWidth,
targetHeight: config.targetHeight,
correctOrientation: config.correctOrientation,
webUseInput: config.webUseInput,
});
console.log('chooseFromGallery result', result);

Expand Down Expand Up @@ -249,16 +248,6 @@ class ChooseFromGalleryConfigurable extends React.Component<
/>
</IonItem>

<IonItem>
<IonLabel>Web Use Input</IonLabel>
<IonToggle
checked={config.webUseInput}
onIonChange={(e) =>
this.updateConfig("webUseInput", e.detail.checked)
}
/>
</IonItem>

<IonButton
expand="block"
color="primary"
Expand Down
6 changes: 5 additions & 1 deletion example-app/src/components/camera/MediaCarousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ const MediaCarousel: React.FC<IMediaCarouselProps> = ({ media, onEditPhoto }) =>
return (
<SwiperSlide key={index}>
{isVideo(item) ? (
<VideoWithMetadata filePath={filePath} metadata={item.metadata} />
<VideoWithMetadata
filePath={filePath}
metadata={item.metadata}
thumbnail={item.thumbnail}
/>
) : (
<PhotoWithMetadata
filePath={filePath}
Expand Down
3 changes: 3 additions & 0 deletions example-app/src/components/camera/VideoWithMetadata.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import { MediaMetadata } from "@capacitor/camera";
interface IVideoWithMetadataProps {
filePath: string;
metadata?: MediaMetadata | string | null;
thumbnail?: string;
}

const VideoWithMetadata: React.FC<IVideoWithMetadataProps> = ({
filePath,
metadata,
thumbnail,
}) => {
const formatMetadata = (meta: MediaMetadata | string | null | undefined): string => {
if (!meta) return '';
Expand Down Expand Up @@ -51,6 +53,7 @@ const VideoWithMetadata: React.FC<IVideoWithMetadataProps> = ({
<div>
<video
src={Capacitor.convertFileSrc(filePath)}
poster={thumbnail ? `data:image/jpeg;base64,${thumbnail}` : undefined}
controls
style={{ width: "100%", maxWidth: "100%" }}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ class GetPhotoConfigurable extends React.Component<
this.props.onPhotoResult({
path: photo.path,
webPath: photo.webPath,
base64String: photo.base64String,
dataUrl: photo.dataUrl,
exif: photo.exif,
});
} catch (e) {
Expand Down Expand Up @@ -105,6 +107,8 @@ class GetPhotoConfigurable extends React.Component<
this.props.onPhotoResult({
path: photo.path,
webPath: photo.webPath,
base64String: photo.base64String,
dataUrl: photo.dataUrl,
exif: photo.exif,
});
} catch (e) {
Expand Down
2 changes: 2 additions & 0 deletions example-app/src/components/camera/old-methods/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,7 @@ export interface PickImagesConfig {
export interface PhotoResult {
path?: string;
webPath?: string;
base64String?: string;
dataUrl?: string;
exif?: any;
}
5 changes: 5 additions & 0 deletions example-app/src/pages/MediaHistoryPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
MediaHistoryItem,
} from "../services/MediaHistoryService";
import { FileViewer } from "@capacitor/file-viewer";
import { Capacitor } from "@capacitor/core";

const MediaHistoryPage: React.FC = () => {
const [history, setHistory] = useState<MediaHistoryItem[]>([]);
Expand All @@ -35,6 +36,10 @@ const MediaHistoryPage: React.FC = () => {

const openFile = async (item: MediaHistoryItem): Promise<void> => {
try {
if (Capacitor.getPlatform() === 'web') {
alert('Opening media from history is not available on Web/PWA.');
return;
}
const filePath = item.uri ?? item.path ?? '';
if (!filePath) {
alert('No file path available for this item');
Expand Down
5 changes: 5 additions & 0 deletions example-app/src/pages/RecordVideoPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { MediaHistoryService } from "../services/MediaHistoryService";
interface IRecordVideoPageState {
filePath: string | null;
metadata: MediaMetadata | string | null;
thumbnail: string | null;
}

class RecordVideoPage extends React.Component<{}, IRecordVideoPageState> {
Expand All @@ -27,13 +28,15 @@ class RecordVideoPage extends React.Component<{}, IRecordVideoPageState> {
this.state = {
filePath: null,
metadata: null,
thumbnail: null,
};
}

handleVideoResult = (result: MediaResult): void => {
this.setState({
filePath: result.uri ?? result.webPath ?? '',
metadata: result.metadata ?? null,
thumbnail: result.thumbnail ?? null,
});

MediaHistoryService.addMedia({
Expand Down Expand Up @@ -65,6 +68,7 @@ class RecordVideoPage extends React.Component<{}, IRecordVideoPageState> {
this.setState({
filePath: null,
metadata: null,
thumbnail: null,
});
};

Expand Down Expand Up @@ -106,6 +110,7 @@ class RecordVideoPage extends React.Component<{}, IRecordVideoPageState> {
<VideoWithMetadata
filePath={this.state.filePath}
metadata={this.state.metadata}
thumbnail={this.state.thumbnail ?? undefined}
/>
</>
)}
Expand Down
12 changes: 10 additions & 2 deletions example-app/src/pages/TakePicturePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,22 @@ class TakePicturePage extends React.Component<{}, ITakePicturePageState> {
handlePhotoResult = (result: {
path?: string;
webPath?: string;
base64String?: string;
dataUrl?: string;
exif?: any;
}): void => {
const filePath =
result.path ??
result.webPath ??
result.dataUrl ??
(result.base64String ? `data:image/jpeg;base64,${result.base64String}` : null);

this.setState({
filePath: result.path ?? result.webPath ?? null,
filePath,
metadata: JSON.stringify(result.exif, null, 2),
});

if (result.path || result.webPath) {
if (filePath) {
MediaHistoryService.addMedia({
mediaType: "photo",
method: "getPhoto",
Expand Down
14 changes: 5 additions & 9 deletions src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,6 @@ export interface TakePhotoOptions {
/**
* Whether or not MediaResult should include its metadata.
* If an error occurs when obtaining the metadata, it will return empty.
* Note: This option is only supported on Android and iOS.
* @default false
*
* @since 8.1.0
Expand Down Expand Up @@ -292,7 +291,6 @@ export interface ChooseFromGalleryOptions {
/**
* Whether or not MediaResult should include its metadata.
* If an error occurs when obtaining the metadata, it will return empty.
* Note: This option is only supported on Android and iOS.
* @default false
*
* @since 8.1.0
Expand Down Expand Up @@ -401,7 +399,6 @@ export interface EditURIPhotoOptions {
/**
* Whether or not MediaResult should include its metadata.
* If an error occurs when obtaining the metadata, it will return empty.
* Note: This option is only supported on Android and iOS.
* @default false
*
* @since 8.1.0
Expand Down Expand Up @@ -446,6 +443,7 @@ export interface MediaResult {
/**
* Returns the thumbnail of the media, base64 encoded.
* On Web, for `MediaType.Photo`, the full image is returned here, also base64 encoded.
* On Web, for `MediaType.Video`, a full-resolution JPEG frame captured from the video is returned, base64 encoded at 80% quality.
*
* @since 8.1.0
*/
Expand Down Expand Up @@ -480,16 +478,14 @@ export interface MediaResult {

export interface MediaMetadata {
/**
* File size of the media, in bytes
* Not available on Web.
* File size of the media, in bytes.
*
* @since 8.1.0
*/
size?: number;

/**
* Only applicable for `MediaType.Video` - the duration of the media, in seconds.
* Not available on Web.
*
* @since 8.1.0
*/
Expand All @@ -499,7 +495,7 @@ export interface MediaMetadata {
* The format of the image, ex: jpeg, png, mp4.
*
* Web supports jpeg, png and gif, but the exact availability may vary depending on the browser.
* gif is only supported for `chooseFromGallery`, and only if `webUseInput` option is set to `true`.
* gif is only supported for `chooseFromGallery` on Web.
*
* @since 8.1.0
*/
Expand All @@ -510,12 +506,12 @@ export interface MediaMetadata {
*
* @since 8.1.0
*/
resolution: string;
resolution?: string;

/**
* The date and time the media was created, in ISO 8601 format.
* If creation date is not available (e.g. Android 7 and below), the last modified date is returned.
* Not available on web.
* For Web, the last modified date is always returned.
*
* @since 8.1.0
*/
Expand Down
Loading
Loading