web_lib

Common web application libraries
git clone https://radroots.dev/git/web_lib.git
Log | Files | Refs | LICENSE

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:
Mclient/package.json | 1+
Aclient/src/capacitor/camera.ts | 131+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mclient/src/capacitor/index.ts | 8+++++++-
Mclient/src/types.ts | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Mclient/src/utils.ts | 13++++++++++++-
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 }; +};