commit 48ad53cafb3f12f4564450cb523f2341b27d3437
parent feb9d5f5f988c1f6f0bf6cfe776990f09a0829a2
Author: triesap <137732411+triesap@users.noreply.github.com>
Date: Fri, 23 Aug 2024 14:06:02 +0000
client: add capacitor camera api
Diffstat:
5 files changed, 207 insertions(+), 4 deletions(-)
diff --git a/client/package.json b/client/package.json
@@ -9,6 +9,7 @@
},
"dependencies": {
"@capacitor/browser": "^6.0.0",
+ "@capacitor/camera": "^6.0.0",
"@capacitor/core": "^6.1.2",
"@capacitor/device": "^6.0.0",
"@capacitor/dialog": "^6.0.0",
diff --git a/client/src/capacitor/camera.ts b/client/src/capacitor/camera.ts
@@ -0,0 +1,131 @@
+
+import { Camera, CameraResultType } from '@capacitor/camera';
+import { ErrorResponse, IClientCamera, OsPhoto, OsPhotoGallery, OsPhotoGallerySelectOptions, OsPhotoSelectOptions, OsPhotosPermissions } from '../types';
+import { err_msg } from '../utils';
+
+
+export class CapacitorClientCamera implements IClientCamera {
+ private parse_camera_result_type(value: string): CameraResultType {
+ switch (value) {
+ case 'uri':
+ return CameraResultType.Uri;
+ case 'base64':
+ return CameraResultType.Base64;
+ case 'dataUrl':
+ return CameraResultType.DataUrl;
+ default:
+ return CameraResultType.Uri;
+ }
+ }
+
+
+ public async enabled(): Promise<OsPhotosPermissions | ErrorResponse> {
+ try {
+ const { camera, photos } = await Camera.checkPermissions();
+ return {
+ camera,
+ photos
+ };
+ } catch (e) {
+ return err_msg(e);
+ };
+ }
+
+ public async request_enabled(): Promise<OsPhotosPermissions | ErrorResponse> {
+ try {
+ const { camera, photos } = await Camera.requestPermissions({
+ permissions: ['camera', 'photos']
+ });
+ return {
+ camera,
+ photos
+ };
+ } catch (e) {
+ return err_msg(e);
+ };
+ }
+
+ public async get_photo(opts: OsPhotoSelectOptions): Promise<OsPhoto | ErrorResponse> {
+ try {
+ const {
+ quality,
+ allow_editing: allowEditing,
+ result_type,
+ save_to_gallery: saveToGallery,
+ width,
+ height,
+ correct_orientation: correctOrientation,
+ prompt_label_header: promptLabelHeader,
+ prompt_label_cancel: promptLabelCancel,
+ prompt_label_photo: promptLabelPhoto,
+ prompt_label_picture: promptLabelPicture
+ } = opts;
+
+
+ const res = await Camera.getPhoto({
+ quality,
+ allowEditing,
+ resultType: this.parse_camera_result_type(result_type),
+ saveToGallery,
+ width,
+ height,
+ correctOrientation,
+ promptLabelHeader,
+ promptLabelCancel,
+ promptLabelPhoto,
+ promptLabelPicture
+ });
+
+ const {
+ base64String: base64_string,
+ dataUrl: data_url,
+ path,
+ webPath: web_path,
+ exif,
+ format,
+ saved
+ } = res;
+
+ return {
+ base64_string,
+ data_url,
+ path,
+ web_path,
+ exif,
+ format,
+ saved
+ };
+ } catch (e) {
+ return err_msg(e);
+ };
+ }
+
+ public async get_photos(opts: OsPhotoGallerySelectOptions): Promise<OsPhotoGallery[] | ErrorResponse> {
+ try {
+ const {
+ quality,
+ width,
+ height,
+ correct_orientation: correctOrientation,
+ limit,
+ } = opts;
+
+ const { photos } = await Camera.pickImages({
+ quality,
+ width,
+ height,
+ correctOrientation,
+ limit,
+ });
+
+ return photos.map(i => ({
+ path: i.path,
+ web_path: i.webPath,
+ exif: i.exif,
+ format: i.format
+ }));
+ } catch (e) {
+ return err_msg(e);
+ };
+ }
+}
diff --git a/client/src/capacitor/index.ts b/client/src/capacitor/index.ts
@@ -1,9 +1,10 @@
import { Capacitor } from "@capacitor/core";
-import type { IClient, IClientBluetoothLe, IClientBrowser, IClientDatePicker, IClientDevice, IClientDialog, IClientGeolocation, IClientHaptics, IClientHttp, IClientKeystore, IClientNetwork, IClientPlatform, IClientPreferences, IClientShare, IClientWifi, IClientWindow } from "../types";
+import type { IClient, IClientBluetoothLe, IClientBrowser, IClientCamera, IClientDatePicker, IClientDevice, IClientDialog, IClientGeolocation, IClientHaptics, IClientHttp, IClientKeystore, IClientNetwork, IClientPlatform, IClientPreferences, IClientShare, IClientWifi, IClientWindow } from "../types";
import { parse_platform } from "../utils";
import { CapacitorClientBluetoothLe } from "./bluetooth-le";
import { CapacitorClientBrowser } from "./browser";
+import { CapacitorClientCamera } from "./camera";
import { CapacitorClientDatePicker } from "./date-picker";
import { CapacitorClientDevice } from "./device";
import { CapacitorClientDialog } from "./dialog";
@@ -34,6 +35,7 @@ export class ClientCapacitor implements IClient {
private _http: IClientHttp = new CapacitorClientHttp();
private _window: IClientWindow = new CapacitorClientWindow();
private _ble: IClientBluetoothLe = new CapacitorClientBluetoothLe();
+ private _camera: IClientCamera = new CapacitorClientCamera();
public get platform() {
return this._platform;
@@ -94,4 +96,8 @@ export class ClientCapacitor implements IClient {
public get blue() {
return this._ble;
}
+
+ public get camera() {
+ return this._camera;
+ }
};
\ No newline at end of file
diff --git a/client/src/types.ts b/client/src/types.ts
@@ -2,6 +2,10 @@ import { type BatteryInfo, type DeviceInfo } from '@capacitor/device';
import { type ScanResult } from '@radroots/capacitor-bluetooth-le';
import { ConnectToWifiResult, type GetCurrentWifiResult, type ScanWifiResult } from '@radroots/capacitor-wifi';
+export type ErrorResponse = {
+ error: string;
+};
+
export type IClient = {
platform: IClientPlatform;
keystore: IClientKeystore;
@@ -18,6 +22,7 @@ export type IClient = {
http: IClientHttp;
window: IClientWindow;
ble: IClientBluetoothLe;
+ camera: IClientCamera;
};
export type IClientPlatform = `androiď` | `ios` | `web`;
@@ -173,4 +178,54 @@ export type IClientBluetoothLe = {
scan(): Promise<boolean>;
select_device(device_id: string): Promise<IClientBluetoothLeScanResult | undefined>;
select_devices(): Promise<IClientBluetoothLeScanResult[] | undefined>;
-};
-\ No newline at end of file
+};
+
+export type OsPhotoSelectOptionsBase = {
+ quality?: number;
+ width?: number;
+ height?: number;
+ correct_orientation?: boolean;
+};
+
+export type OsPhotoSelectOptions = OsPhotoSelectOptionsBase & {
+ allow_editing?: boolean;
+ result_type: 'uri' | 'base64' | 'dataUrl';
+ save_to_gallery?: boolean;
+ prompt_label_header?: string;
+ prompt_label_cancel?: string;
+ prompt_label_photo?: string;
+ prompt_label_picture?: string;
+};
+
+export type OsPhotoGallerySelectOptions = OsPhotoSelectOptionsBase & {
+ limit?: number;
+};
+
+export type OsPhoto = {
+ base64_string?: string;
+ data_url?: string;
+ path?: string;
+ web_path?: string;
+ exif?: any;
+ format: string;
+ saved: boolean;
+};
+
+export type OsPhotoGallery = {
+ path?: string;
+ web_path: string;
+ exif?: any;
+ format: string;
+};
+
+export type OsPhotosPermissions = {
+ camera: string;
+ photos: string;
+};
+
+export type IClientCamera = {
+ enabled(): Promise<OsPhotosPermissions | ErrorResponse>;
+ request_enabled(): Promise<OsPhotosPermissions | ErrorResponse>;
+ get_photo(opts: OsPhotoSelectOptions): Promise<OsPhoto | ErrorResponse>;
+ get_photos(opts: OsPhotoGallerySelectOptions): Promise<OsPhotoGallery[] | ErrorResponse>;
+};
diff --git a/client/src/utils.ts b/client/src/utils.ts
@@ -1,4 +1,10 @@
-import type { IClientPlatform } from "./types";
+import type { ErrorResponse, IClientPlatform } from "./types";
+
+/*export enum IClientCameraResultTypeEnum {
+ Uri = "uri",
+ Base64 = "base64",
+ DataUrl = "dataUrl"
+};*/
export function parse_platform(str: string): IClientPlatform {
switch (str) {
@@ -14,3 +20,8 @@ export function parse_platform(str: string): IClientPlatform {
export function fmt_location_coords(number: number): number {
return Math.round(number * 1e7) / 1e7;
};
+
+export const err_msg = (e: unknown): ErrorResponse => {
+ const error = (e as Error).message ? (e as Error).message : String(e);
+ return { error };
+};