capacitor-camera-multicapture 0.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CameraMultiCapture.podspec +17 -0
- package/LICENSE +21 -0
- package/Package.swift +28 -0
- package/README.md +551 -0
- package/android/build.gradle +69 -0
- package/android/src/main/AndroidManifest.xml +6 -0
- package/android/src/main/java/dev/hemang/cameramulticapture/CameraConfig.java +45 -0
- package/android/src/main/java/dev/hemang/cameramulticapture/CameraConfigMapper.java +98 -0
- package/android/src/main/java/dev/hemang/cameramulticapture/CameraMultiCapture.java +10 -0
- package/android/src/main/java/dev/hemang/cameramulticapture/CameraMultiCapturePlugin.java +1340 -0
- package/android/src/main/java/dev/hemang/cameramulticapture/ExifWrapper.java +108 -0
- package/android/src/main/java/dev/hemang/cameramulticapture/GenericUploadWorker.java +173 -0
- package/android/src/main/java/dev/hemang/cameramulticapture/ImageUtils.java +215 -0
- package/android/src/main/java/dev/hemang/cameramulticapture/PluginVersion.java +6 -0
- package/android/src/main/java/dev/hemang/cameramulticapture/ThumbnailGenerator.java +48 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/esm/controllers/camera-controller.d.ts +127 -0
- package/dist/esm/controllers/camera-controller.js +388 -0
- package/dist/esm/controllers/camera-controller.js.map +1 -0
- package/dist/esm/controllers/gallery-controller.d.ts +66 -0
- package/dist/esm/controllers/gallery-controller.js +333 -0
- package/dist/esm/controllers/gallery-controller.js.map +1 -0
- package/dist/esm/definitions.d.ts +372 -0
- package/dist/esm/definitions.js +6 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/overlay-manager.d.ts +124 -0
- package/dist/esm/overlay-manager.js +732 -0
- package/dist/esm/overlay-manager.js.map +1 -0
- package/dist/esm/overlay.d.ts +2 -0
- package/dist/esm/overlay.js +39 -0
- package/dist/esm/overlay.js.map +1 -0
- package/dist/esm/registration.d.ts +5 -0
- package/dist/esm/registration.js +8 -0
- package/dist/esm/registration.js.map +1 -0
- package/dist/esm/types/ui-types.d.ts +78 -0
- package/dist/esm/types/ui-types.js +2 -0
- package/dist/esm/types/ui-types.js.map +1 -0
- package/dist/esm/ui/capture-gesture-handler.d.ts +15 -0
- package/dist/esm/ui/capture-gesture-handler.js +87 -0
- package/dist/esm/ui/capture-gesture-handler.js.map +1 -0
- package/dist/esm/ui/default-styles.d.ts +27 -0
- package/dist/esm/ui/default-styles.js +134 -0
- package/dist/esm/ui/default-styles.js.map +1 -0
- package/dist/esm/ui/image-editor.d.ts +10 -0
- package/dist/esm/ui/image-editor.js +103 -0
- package/dist/esm/ui/image-editor.js.map +1 -0
- package/dist/esm/ui/layout-manager.d.ts +42 -0
- package/dist/esm/ui/layout-manager.js +199 -0
- package/dist/esm/ui/layout-manager.js.map +1 -0
- package/dist/esm/ui/media-viewer.d.ts +2 -0
- package/dist/esm/ui/media-viewer.js +267 -0
- package/dist/esm/ui/media-viewer.js.map +1 -0
- package/dist/esm/ui/pinch-zoom-handler.d.ts +37 -0
- package/dist/esm/ui/pinch-zoom-handler.js +118 -0
- package/dist/esm/ui/pinch-zoom-handler.js.map +1 -0
- package/dist/esm/ui/ui-factory.d.ts +39 -0
- package/dist/esm/ui/ui-factory.js +272 -0
- package/dist/esm/ui/ui-factory.js.map +1 -0
- package/dist/esm/version.d.ts +1 -0
- package/dist/esm/version.js +3 -0
- package/dist/esm/version.js.map +1 -0
- package/dist/esm/web.d.ts +69 -0
- package/dist/esm/web.js +122 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +6274 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +6276 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/CameraMultiCapturePlugin/CameraMultiCapture.swift +8 -0
- package/ios/Sources/CameraMultiCapturePlugin/CameraMultiCapturePlugin.swift +1551 -0
- package/ios/Sources/CameraMultiCapturePlugin/PluginVersion.swift +2 -0
- package/ios/Tests/CameraMultiCapturePluginTests/CameraMultiCapturePluginTests.swift +15 -0
- package/package.json +93 -0
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Controller for camera operations
|
|
3
|
+
*/
|
|
4
|
+
import { Capacitor } from '@capacitor/core';
|
|
5
|
+
import { TorchState } from '../definitions';
|
|
6
|
+
/**
|
|
7
|
+
* Manages camera operations
|
|
8
|
+
*/
|
|
9
|
+
export class CameraController {
|
|
10
|
+
constructor(plugin, options) {
|
|
11
|
+
var _a;
|
|
12
|
+
this.flashMode = 'off';
|
|
13
|
+
this.flashAutoModeEnabled = true;
|
|
14
|
+
this.torchState = TorchState.Off;
|
|
15
|
+
this.isRecording = false;
|
|
16
|
+
this.currentZoom = 1;
|
|
17
|
+
this.preRecordingState = null;
|
|
18
|
+
this.availableCameras = null;
|
|
19
|
+
this.plugin = plugin;
|
|
20
|
+
this.options = options;
|
|
21
|
+
this.flashAutoModeEnabled = (_a = options.flashAutoModeEnabled) !== null && _a !== void 0 ? _a : true;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Initializes the camera
|
|
25
|
+
*/
|
|
26
|
+
async initialize(containerElement, quality) {
|
|
27
|
+
try {
|
|
28
|
+
const rect = containerElement.getBoundingClientRect();
|
|
29
|
+
const startOptions = {
|
|
30
|
+
quality,
|
|
31
|
+
direction: 'back',
|
|
32
|
+
previewRect: {
|
|
33
|
+
width: rect.width,
|
|
34
|
+
height: rect.height,
|
|
35
|
+
x: rect.x,
|
|
36
|
+
y: rect.y
|
|
37
|
+
},
|
|
38
|
+
containerId: containerElement.id || 'camera-container',
|
|
39
|
+
maxRecordingDuration: this.options.maxRecordingDuration,
|
|
40
|
+
enableSaving: this.options.enableSaving,
|
|
41
|
+
galleryAlbumName: this.options.galleryAlbumName,
|
|
42
|
+
};
|
|
43
|
+
await this.plugin.start(startOptions);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
console.error('Failed to start camera', error);
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Captures an image
|
|
52
|
+
*/
|
|
53
|
+
async captureImage() {
|
|
54
|
+
var _a;
|
|
55
|
+
try {
|
|
56
|
+
const result = await this.plugin.capture();
|
|
57
|
+
console.log('Capture result:', result);
|
|
58
|
+
if (!((_a = result === null || result === void 0 ? void 0 : result.value) === null || _a === void 0 ? void 0 : _a.uri)) {
|
|
59
|
+
throw new Error('No URI returned from native capture');
|
|
60
|
+
}
|
|
61
|
+
result.value.webPath = Capacitor.convertFileSrc(result.value.uri);
|
|
62
|
+
return result === null || result === void 0 ? void 0 : result.value;
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
console.error('Failed to capture photo', error);
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async startVideoRecording() {
|
|
70
|
+
try {
|
|
71
|
+
this.preRecordingState = {
|
|
72
|
+
flash: this.flashMode,
|
|
73
|
+
torch: this.torchState,
|
|
74
|
+
zoom: this.currentZoom,
|
|
75
|
+
};
|
|
76
|
+
await this.plugin.startVideoRecording();
|
|
77
|
+
this.isRecording = true;
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
this.preRecordingState = null;
|
|
81
|
+
console.error('Failed to start video recording', error);
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async stopVideoRecording() {
|
|
86
|
+
var _a;
|
|
87
|
+
try {
|
|
88
|
+
const result = await this.plugin.stopVideoRecording();
|
|
89
|
+
this.isRecording = false;
|
|
90
|
+
if (!((_a = result === null || result === void 0 ? void 0 : result.value) === null || _a === void 0 ? void 0 : _a.uri)) {
|
|
91
|
+
throw new Error('No URI returned from native video recording');
|
|
92
|
+
}
|
|
93
|
+
result.value.webPath = Capacitor.convertFileSrc(result.value.uri);
|
|
94
|
+
await this.restorePreRecordingState();
|
|
95
|
+
return result.value;
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
this.isRecording = false;
|
|
99
|
+
await this.restorePreRecordingState();
|
|
100
|
+
console.error('Failed to stop video recording', error);
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async restorePreRecordingState() {
|
|
105
|
+
const saved = this.preRecordingState;
|
|
106
|
+
this.preRecordingState = null;
|
|
107
|
+
if (!saved)
|
|
108
|
+
return;
|
|
109
|
+
try {
|
|
110
|
+
await this.setFlash(saved.flash);
|
|
111
|
+
await this.setTorch(saved.torch);
|
|
112
|
+
await this.setZoom(saved.zoom);
|
|
113
|
+
}
|
|
114
|
+
catch (e) {
|
|
115
|
+
console.warn('Failed to restore pre-recording camera state', e);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Returns whether video recording is currently active.
|
|
120
|
+
*/
|
|
121
|
+
getRecordingState() {
|
|
122
|
+
return this.isRecording;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Sets the zoom level
|
|
126
|
+
*/
|
|
127
|
+
async setZoom(level) {
|
|
128
|
+
try {
|
|
129
|
+
this.currentZoom = level; // important
|
|
130
|
+
await this.plugin.setZoom({ zoom: level });
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
console.error('Failed to set zoom', error);
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Gets the current zoom level (tracked after setZoom calls)
|
|
139
|
+
*/
|
|
140
|
+
getCurrentZoom() {
|
|
141
|
+
return this.currentZoom;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Gets available cameras information
|
|
145
|
+
*/
|
|
146
|
+
async getAvailableCameras() {
|
|
147
|
+
try {
|
|
148
|
+
if (!this.availableCameras) {
|
|
149
|
+
this.availableCameras = await this.plugin.getAvailableCameras();
|
|
150
|
+
}
|
|
151
|
+
return this.availableCameras;
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
console.error('Failed to get available cameras', error);
|
|
155
|
+
// Return default values
|
|
156
|
+
return {
|
|
157
|
+
hasUltrawide: false,
|
|
158
|
+
hasWide: true,
|
|
159
|
+
hasTelephoto: false,
|
|
160
|
+
wideZoomFactor: 1.0
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Switches to a physical camera based on zoom factor
|
|
166
|
+
* This will switch to the appropriate lens (ultrawide, wide, telephoto)
|
|
167
|
+
*/
|
|
168
|
+
async switchToPhysicalCamera(zoomFactor) {
|
|
169
|
+
try {
|
|
170
|
+
await this.plugin.switchToPhysicalCamera({ zoomFactor });
|
|
171
|
+
this.currentZoom = zoomFactor;
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
console.error('Failed to switch physical camera', error);
|
|
175
|
+
await this.setZoom(zoomFactor);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Gets available zoom levels for the current camera
|
|
180
|
+
*/
|
|
181
|
+
async getAvailableZoomLevels() {
|
|
182
|
+
return await this.plugin.getAvailableZoomLevels();
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Switches between front and back camera
|
|
186
|
+
*/
|
|
187
|
+
async switchCamera() {
|
|
188
|
+
try {
|
|
189
|
+
await this.plugin.switchCamera();
|
|
190
|
+
// Invalidate cached camera info since capabilities differ per camera position
|
|
191
|
+
this.availableCameras = null;
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
console.error('Failed to switch camera', error);
|
|
195
|
+
throw error;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Stops the camera
|
|
200
|
+
*/
|
|
201
|
+
async stop() {
|
|
202
|
+
try {
|
|
203
|
+
await this.plugin.stop();
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
console.warn('Failed to stop camera', error);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Sets the flash mode
|
|
211
|
+
*/
|
|
212
|
+
async setFlash(mode) {
|
|
213
|
+
try {
|
|
214
|
+
await this.plugin.setFlash({ flashMode: mode });
|
|
215
|
+
this.flashMode = mode;
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
console.error('Failed to set flash mode', error);
|
|
219
|
+
throw error;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Gets the current flash mode
|
|
224
|
+
*/
|
|
225
|
+
getFlashMode() {
|
|
226
|
+
return this.flashMode;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Toggles flash mode between off, on, and optionally auto
|
|
230
|
+
*/
|
|
231
|
+
async toggleFlash() {
|
|
232
|
+
let newMode;
|
|
233
|
+
if (this.flashAutoModeEnabled) {
|
|
234
|
+
// 3-mode cycle: off → on → auto → off
|
|
235
|
+
switch (this.flashMode) {
|
|
236
|
+
case 'off':
|
|
237
|
+
newMode = 'on';
|
|
238
|
+
break;
|
|
239
|
+
case 'on':
|
|
240
|
+
newMode = 'auto';
|
|
241
|
+
break;
|
|
242
|
+
case 'auto':
|
|
243
|
+
default:
|
|
244
|
+
newMode = 'off';
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
// 2-mode cycle: off → on → off
|
|
250
|
+
switch (this.flashMode) {
|
|
251
|
+
case 'off':
|
|
252
|
+
newMode = 'on';
|
|
253
|
+
break;
|
|
254
|
+
case 'on':
|
|
255
|
+
case 'auto': // If somehow in auto mode, go to off
|
|
256
|
+
default:
|
|
257
|
+
newMode = 'off';
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
await this.setFlash(newMode);
|
|
262
|
+
return newMode;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Gets whether auto mode is enabled
|
|
266
|
+
*/
|
|
267
|
+
isFlashAutoModeEnabled() {
|
|
268
|
+
return this.flashAutoModeEnabled;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Sets the torch (flashlight) state.
|
|
272
|
+
*/
|
|
273
|
+
async setTorch(state) {
|
|
274
|
+
try {
|
|
275
|
+
await this.plugin.setTorch({ enabled: state === TorchState.On });
|
|
276
|
+
this.torchState = state;
|
|
277
|
+
}
|
|
278
|
+
catch (error) {
|
|
279
|
+
console.error('Failed to set torch', error);
|
|
280
|
+
throw error;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Gets the current torch state.
|
|
285
|
+
*/
|
|
286
|
+
async getTorch() {
|
|
287
|
+
try {
|
|
288
|
+
const result = await this.plugin.getTorch();
|
|
289
|
+
this.torchState = result.enabled ? TorchState.On : TorchState.Off;
|
|
290
|
+
return this.torchState;
|
|
291
|
+
}
|
|
292
|
+
catch (error) {
|
|
293
|
+
console.error('Failed to get torch state', error);
|
|
294
|
+
return this.torchState;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Toggles the torch state and returns the new value.
|
|
299
|
+
*/
|
|
300
|
+
async toggleTorch() {
|
|
301
|
+
const current = await this.getTorch();
|
|
302
|
+
const next = current === TorchState.On ? TorchState.Off : TorchState.On;
|
|
303
|
+
await this.setTorch(next);
|
|
304
|
+
return next;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Updates the camera preview rectangle dimensions
|
|
308
|
+
* Call this method when the container size changes (e.g., orientation change)
|
|
309
|
+
*/
|
|
310
|
+
async refresh() {
|
|
311
|
+
setTimeout(async () => {
|
|
312
|
+
try {
|
|
313
|
+
const containerElement = document.getElementById(this.options.containerId);
|
|
314
|
+
if (!containerElement) {
|
|
315
|
+
throw new Error(`Container with ID ${this.options.containerId} not found`);
|
|
316
|
+
}
|
|
317
|
+
const rect = containerElement.getBoundingClientRect();
|
|
318
|
+
await this.plugin.updatePreviewRect({
|
|
319
|
+
width: rect.width,
|
|
320
|
+
height: rect.height,
|
|
321
|
+
x: rect.x,
|
|
322
|
+
y: rect.y
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
console.error('Failed to update preview rect', error);
|
|
327
|
+
throw error;
|
|
328
|
+
}
|
|
329
|
+
}, 100);
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Gets smart zoom levels that include physical camera switches
|
|
333
|
+
* Returns an array of zoom levels and whether each is a physical camera
|
|
334
|
+
*/
|
|
335
|
+
async getSmartZoomLevels() {
|
|
336
|
+
const cameras = await this.getAvailableCameras();
|
|
337
|
+
const zoomLevels = [];
|
|
338
|
+
// Add ultrawide if available
|
|
339
|
+
if (cameras.hasUltrawide && cameras.ultrawideZoomFactor) {
|
|
340
|
+
zoomLevels.push({ level: cameras.ultrawideZoomFactor, isPhysicalCamera: true });
|
|
341
|
+
}
|
|
342
|
+
// Always add wide (1x)
|
|
343
|
+
zoomLevels.push({ level: cameras.wideZoomFactor, isPhysicalCamera: true });
|
|
344
|
+
// Add telephoto at its real zoom factor (derived from virtual device switch-over points)
|
|
345
|
+
if (cameras.hasTelephoto && cameras.telephotoZoomFactor) {
|
|
346
|
+
zoomLevels.push({ level: cameras.telephotoZoomFactor, isPhysicalCamera: true });
|
|
347
|
+
}
|
|
348
|
+
// Add intermediate and extended digital zoom levels
|
|
349
|
+
const digitalZoomLevels = [2, 3, 5, 10];
|
|
350
|
+
const zoomInfo = await this.getAvailableZoomLevels();
|
|
351
|
+
for (const level of digitalZoomLevels) {
|
|
352
|
+
// Only add if not already covered by a physical camera and within device capabilities
|
|
353
|
+
const alreadyCovered = zoomLevels.some(z => Math.abs(z.level - level) < 0.1);
|
|
354
|
+
if (!alreadyCovered && level > cameras.wideZoomFactor && level <= zoomInfo.maxZoom) {
|
|
355
|
+
zoomLevels.push({ level, isPhysicalCamera: false });
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
// Sort by zoom level
|
|
359
|
+
zoomLevels.sort((a, b) => a.level - b.level);
|
|
360
|
+
return zoomLevels;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Performs smart zoom - switches physical cameras when appropriate
|
|
364
|
+
*/
|
|
365
|
+
async performSmartZoom(targetZoom) {
|
|
366
|
+
const cameras = await this.getAvailableCameras();
|
|
367
|
+
// Determine if this zoom level should trigger a physical camera switch
|
|
368
|
+
const physicalCameraZooms = [];
|
|
369
|
+
if (cameras.hasUltrawide && cameras.ultrawideZoomFactor) {
|
|
370
|
+
physicalCameraZooms.push(cameras.ultrawideZoomFactor);
|
|
371
|
+
}
|
|
372
|
+
physicalCameraZooms.push(cameras.wideZoomFactor);
|
|
373
|
+
if (cameras.hasTelephoto && cameras.telephotoZoomFactor) {
|
|
374
|
+
physicalCameraZooms.push(cameras.telephotoZoomFactor);
|
|
375
|
+
}
|
|
376
|
+
// Check if target zoom matches a physical camera
|
|
377
|
+
const matchingPhysicalCamera = physicalCameraZooms.find(z => Math.abs(z - targetZoom) < 0.1);
|
|
378
|
+
if (matchingPhysicalCamera) {
|
|
379
|
+
// Switch to the physical camera
|
|
380
|
+
await this.switchToPhysicalCamera(targetZoom);
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
// Use digital zoom
|
|
384
|
+
await this.setZoom(targetZoom);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
//# sourceMappingURL=camera-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"camera-controller.js","sourceRoot":"","sources":["../../../src/controllers/camera-controller.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAc5C;;GAEG;AACH,MAAM,OAAO,gBAAgB;IAkB3B,YAAY,MAAgC,EAAE,OAA+B;;QAfrE,cAAS,GAA0B,KAAK,CAAC;QACzC,yBAAoB,GAAY,IAAI,CAAC;QACrC,eAAU,GAAe,UAAU,CAAC,GAAG,CAAC;QACxC,gBAAW,GAAG,KAAK,CAAC;QACpB,gBAAW,GAAG,CAAC,CAAC;QAChB,sBAAiB,GAA6E,IAAI,CAAC;QACnG,qBAAgB,GAOb,IAAI,CAAC;QAGd,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,oBAAoB,GAAG,MAAA,OAAO,CAAC,oBAAoB,mCAAI,IAAI,CAAC;IACnE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,gBAA6B,EAAE,OAAe;QAC7D,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,gBAAgB,CAAC,qBAAqB,EAAE,CAAC;YACtD,MAAM,YAAY,GAAQ;gBACxB,OAAO;gBACP,SAAS,EAAE,MAAM;gBACjB,WAAW,EAAE;oBACX,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,CAAC,EAAE,IAAI,CAAC,CAAC;oBACT,CAAC,EAAE,IAAI,CAAC,CAAC;iBACV;gBACD,WAAW,EAAE,gBAAgB,CAAC,EAAE,IAAI,kBAAkB;gBACtD,oBAAoB,EAAE,IAAI,CAAC,OAAO,CAAC,oBAAoB;gBACvD,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY;gBACvC,gBAAgB,EAAE,IAAI,CAAC,OAAO,CAAC,gBAAgB;aAChD,CAAC;YAEF,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;YAC/C,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY;;QAChB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;YAEvC,IAAI,CAAC,CAAA,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,0CAAE,GAAG,CAAA,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;YACzD,CAAC;YAED,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAClE,OAAO,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;YAChD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,mBAAmB;QACvB,IAAI,CAAC;YACH,IAAI,CAAC,iBAAiB,GAAG;gBACvB,KAAK,EAAE,IAAI,CAAC,SAAS;gBACrB,KAAK,EAAE,IAAI,CAAC,UAAU;gBACtB,IAAI,EAAE,IAAI,CAAC,WAAW;aACvB,CAAC;YACF,MAAM,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC;YACxC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;YAC9B,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;YACxD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,kBAAkB;;QACtB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;YACtD,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YAEzB,IAAI,CAAC,CAAA,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,0CAAE,GAAG,CAAA,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;YACjE,CAAC;YAED,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAClE,MAAM,IAAI,CAAC,wBAAwB,EAAE,CAAC;YACtC,OAAO,MAAM,CAAC,KAAK,CAAC;QACtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,MAAM,IAAI,CAAC,wBAAwB,EAAE,CAAC;YACtC,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;YACvD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,wBAAwB;QACpC,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC;QACrC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACjC,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACjC,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,8CAA8C,EAAE,CAAC,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED;;OAEG;IACH,iBAAiB;QACf,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,KAAa;QACzB,IAAI,CAAC;YACH,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAG,YAAY;YACxC,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;YAC3C,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,mBAAmB;QAQvB,IAAI,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBAC3B,IAAI,CAAC,gBAAgB,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC;YAClE,CAAC;YACD,OAAO,IAAI,CAAC,gBAAgB,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;YACxD,wBAAwB;YACxB,OAAO;gBACL,YAAY,EAAE,KAAK;gBACnB,OAAO,EAAE,IAAI;gBACb,YAAY,EAAE,KAAK;gBACnB,cAAc,EAAE,GAAG;aACpB,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,sBAAsB,CAAC,UAAkB;QAC7C,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;YACzD,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;QAChC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;YACzD,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,sBAAsB;QAC1B,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,sBAAsB,EAAE,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;YACjC,8EAA8E;YAC9E,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;YAChD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,IAA2B;QACxC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAChD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;YACjD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW;QACf,IAAI,OAA8B,CAAC;QAEnC,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC9B,sCAAsC;YACtC,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;gBACvB,KAAK,KAAK;oBACR,OAAO,GAAG,IAAI,CAAC;oBACf,MAAM;gBACR,KAAK,IAAI;oBACP,OAAO,GAAG,MAAM,CAAC;oBACjB,MAAM;gBACR,KAAK,MAAM,CAAC;gBACZ;oBACE,OAAO,GAAG,KAAK,CAAC;oBAChB,MAAM;YACV,CAAC;QACH,CAAC;aAAM,CAAC;YACN,+BAA+B;YAC/B,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;gBACvB,KAAK,KAAK;oBACR,OAAO,GAAG,IAAI,CAAC;oBACf,MAAM;gBACR,KAAK,IAAI,CAAC;gBACV,KAAK,MAAM,CAAC,CAAC,qCAAqC;gBAClD;oBACE,OAAO,GAAG,KAAK,CAAC;oBAChB,MAAM;YACV,CAAC;QACH,CAAC;QAED,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC7B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,sBAAsB;QACpB,OAAO,IAAI,CAAC,oBAAoB,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,KAAiB;QAC9B,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,KAAK,KAAK,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;YACjE,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;YAC5C,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC5C,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;YAClE,OAAO,IAAI,CAAC,UAAU,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;YAClD,OAAO,IAAI,CAAC,UAAU,CAAC;QACzB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW;QACf,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,OAAO,KAAK,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC;QACxE,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,OAAO;QAEX,UAAU,CAAC,KAAK,IAAI,EAAE;YACtB,IAAI,CAAC;gBACH,MAAM,gBAAgB,GAAG,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;gBAC3E,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACtB,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,CAAC,OAAO,CAAC,WAAW,YAAY,CAAC,CAAC;gBAC7E,CAAC;gBACD,MAAM,IAAI,GAAG,gBAAgB,CAAC,qBAAqB,EAAE,CAAC;gBACtD,MAAM,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC;oBAClC,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,CAAC,EAAE,IAAI,CAAC,CAAC;oBACT,CAAC,EAAE,IAAI,CAAC,CAAC;iBACV,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;gBACpD,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,kBAAkB;QACtB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACjD,MAAM,UAAU,GAAmD,EAAE,CAAC;QAEtE,6BAA6B;QAC7B,IAAI,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;YACxD,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,mBAAmB,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;QAClF,CAAC;QAED,uBAAuB;QACvB,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,cAAc,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3E,yFAAyF;QACzF,IAAI,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;YACxD,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,mBAAmB,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;QAClF,CAAC;QAED,oDAAoD;QACpD,MAAM,iBAAiB,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACxC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,sBAAsB,EAAE,CAAC;QACrD,KAAK,MAAM,KAAK,IAAI,iBAAiB,EAAE,CAAC;YACtC,sFAAsF;YACtF,MAAM,cAAc,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;YAC7E,IAAI,CAAC,cAAc,IAAI,KAAK,GAAG,OAAO,CAAC,cAAc,IAAI,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACnF,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;QAED,qBAAqB;QACrB,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAE7C,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB,CAAC,UAAkB;QACvC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAEjD,uEAAuE;QACvE,MAAM,mBAAmB,GAAa,EAAE,CAAC;QACzC,IAAI,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;YACxD,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACxD,CAAC;QACD,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACjD,IAAI,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;YACxD,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACxD,CAAC;QAED,iDAAiD;QACjD,MAAM,sBAAsB,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC;QAE7F,IAAI,sBAAsB,EAAE,CAAC;YAC3B,gCAAgC;YAChC,MAAM,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,mBAAmB;YACnB,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;CACF","sourcesContent":["/**\n * Controller for camera operations\n */\nimport { Capacitor } from '@capacitor/core';\nimport { TorchState } from '../definitions';\nimport type { CameraImageData, CameraMultiCapturePlugin, CameraVideoData } from '../definitions';\nimport type { CameraOverlayUIOptions } from '../types/ui-types';\n\n/**\n * Interface for camera rectangle dimensions\n */\nexport interface CameraRect {\n width: number;\n height: number;\n x: number;\n y: number;\n}\n\n/**\n * Manages camera operations\n */\nexport class CameraController {\n private plugin: CameraMultiCapturePlugin;\n private options: CameraOverlayUIOptions;\n private flashMode: 'on' | 'off' | 'auto' = 'off';\n private flashAutoModeEnabled: boolean = true;\n private torchState: TorchState = TorchState.Off;\n private isRecording = false;\n private currentZoom = 1;\n private preRecordingState: { flash: 'on' | 'off' | 'auto'; torch: TorchState; zoom: number } | null = null;\n private availableCameras: {\n hasUltrawide: boolean;\n hasWide: boolean;\n hasTelephoto: boolean;\n ultrawideZoomFactor?: number;\n wideZoomFactor: number;\n telephotoZoomFactor?: number;\n } | null = null;\n \n constructor(plugin: CameraMultiCapturePlugin, options: CameraOverlayUIOptions) {\n this.plugin = plugin;\n this.options = options;\n this.flashAutoModeEnabled = options.flashAutoModeEnabled ?? true;\n }\n \n /**\n * Initializes the camera\n */\n async initialize(containerElement: HTMLElement, quality: number): Promise<void> {\n try {\n const rect = containerElement.getBoundingClientRect();\n const startOptions: any = {\n quality,\n direction: 'back',\n previewRect: {\n width: rect.width,\n height: rect.height,\n x: rect.x,\n y: rect.y\n },\n containerId: containerElement.id || 'camera-container',\n maxRecordingDuration: this.options.maxRecordingDuration,\n enableSaving: this.options.enableSaving,\n galleryAlbumName: this.options.galleryAlbumName,\n };\n\n await this.plugin.start(startOptions);\n } catch (error) {\n console.error('Failed to start camera', error);\n throw error;\n }\n }\n \n /**\n * Captures an image\n */\n async captureImage(): Promise<CameraImageData | undefined> {\n try {\n const result = await this.plugin.capture();\n console.log('Capture result:', result);\n \n if (!result?.value?.uri) {\n throw new Error('No URI returned from native capture');\n }\n \n result.value.webPath = Capacitor.convertFileSrc(result.value.uri);\n return result?.value;\n } catch (error) {\n console.error('Failed to capture photo', error);\n throw error;\n }\n }\n\n async startVideoRecording(): Promise<void> {\n try {\n this.preRecordingState = {\n flash: this.flashMode,\n torch: this.torchState,\n zoom: this.currentZoom,\n };\n await this.plugin.startVideoRecording();\n this.isRecording = true;\n } catch (error) {\n this.preRecordingState = null;\n console.error('Failed to start video recording', error);\n throw error;\n }\n }\n\n async stopVideoRecording(): Promise<CameraVideoData | undefined> {\n try {\n const result = await this.plugin.stopVideoRecording();\n this.isRecording = false;\n\n if (!result?.value?.uri) {\n throw new Error('No URI returned from native video recording');\n }\n\n result.value.webPath = Capacitor.convertFileSrc(result.value.uri);\n await this.restorePreRecordingState();\n return result.value;\n } catch (error) {\n this.isRecording = false;\n await this.restorePreRecordingState();\n console.error('Failed to stop video recording', error);\n throw error;\n }\n }\n\n private async restorePreRecordingState(): Promise<void> {\n const saved = this.preRecordingState;\n this.preRecordingState = null;\n if (!saved) return;\n try {\n await this.setFlash(saved.flash);\n await this.setTorch(saved.torch);\n await this.setZoom(saved.zoom);\n } catch (e) {\n console.warn('Failed to restore pre-recording camera state', e);\n }\n }\n\n /**\n * Returns whether video recording is currently active.\n */\n getRecordingState(): boolean {\n return this.isRecording;\n }\n \n /**\n * Sets the zoom level\n */\n async setZoom(level: number): Promise<void> {\n try {\n this.currentZoom = level; // important\n await this.plugin.setZoom({ zoom: level });\n } catch (error) {\n console.error('Failed to set zoom', error);\n throw error;\n }\n }\n\n /**\n * Gets the current zoom level (tracked after setZoom calls)\n */\n getCurrentZoom(): number {\n return this.currentZoom;\n }\n\n /**\n * Gets available cameras information\n */\n async getAvailableCameras(): Promise<{\n hasUltrawide: boolean;\n hasWide: boolean;\n hasTelephoto: boolean;\n ultrawideZoomFactor?: number;\n wideZoomFactor: number;\n telephotoZoomFactor?: number;\n }> {\n try {\n if (!this.availableCameras) {\n this.availableCameras = await this.plugin.getAvailableCameras();\n }\n return this.availableCameras;\n } catch (error) {\n console.error('Failed to get available cameras', error);\n // Return default values\n return {\n hasUltrawide: false,\n hasWide: true,\n hasTelephoto: false,\n wideZoomFactor: 1.0\n };\n }\n }\n\n /**\n * Switches to a physical camera based on zoom factor\n * This will switch to the appropriate lens (ultrawide, wide, telephoto)\n */\n async switchToPhysicalCamera(zoomFactor: number): Promise<void> {\n try {\n await this.plugin.switchToPhysicalCamera({ zoomFactor });\n this.currentZoom = zoomFactor;\n } catch (error) {\n console.error('Failed to switch physical camera', error);\n await this.setZoom(zoomFactor);\n }\n }\n\n /**\n * Gets available zoom levels for the current camera\n */\n async getAvailableZoomLevels(): Promise<{ minZoom: number; maxZoom: number; presetLevels: number[] }> {\n return await this.plugin.getAvailableZoomLevels();\n }\n \n /**\n * Switches between front and back camera\n */\n async switchCamera(): Promise<void> {\n try {\n await this.plugin.switchCamera();\n // Invalidate cached camera info since capabilities differ per camera position\n this.availableCameras = null;\n } catch (error) {\n console.error('Failed to switch camera', error);\n throw error;\n }\n }\n \n /**\n * Stops the camera\n */\n async stop(): Promise<void> {\n try {\n await this.plugin.stop();\n } catch (error) {\n console.warn('Failed to stop camera', error);\n }\n }\n\n /**\n * Sets the flash mode\n */\n async setFlash(mode: 'on' | 'off' | 'auto'): Promise<void> {\n try {\n await this.plugin.setFlash({ flashMode: mode });\n this.flashMode = mode;\n } catch (error) {\n console.error('Failed to set flash mode', error);\n throw error;\n }\n }\n\n /**\n * Gets the current flash mode\n */\n getFlashMode(): 'on' | 'off' | 'auto' {\n return this.flashMode;\n }\n\n /**\n * Toggles flash mode between off, on, and optionally auto\n */\n async toggleFlash(): Promise<'on' | 'off' | 'auto'> {\n let newMode: 'on' | 'off' | 'auto';\n \n if (this.flashAutoModeEnabled) {\n // 3-mode cycle: off → on → auto → off\n switch (this.flashMode) {\n case 'off':\n newMode = 'on';\n break;\n case 'on':\n newMode = 'auto';\n break;\n case 'auto':\n default:\n newMode = 'off';\n break;\n }\n } else {\n // 2-mode cycle: off → on → off\n switch (this.flashMode) {\n case 'off':\n newMode = 'on';\n break;\n case 'on':\n case 'auto': // If somehow in auto mode, go to off\n default:\n newMode = 'off';\n break;\n }\n }\n \n await this.setFlash(newMode);\n return newMode;\n }\n\n /**\n * Gets whether auto mode is enabled\n */\n isFlashAutoModeEnabled(): boolean {\n return this.flashAutoModeEnabled;\n }\n\n /**\n * Sets the torch (flashlight) state.\n */\n async setTorch(state: TorchState): Promise<void> {\n try {\n await this.plugin.setTorch({ enabled: state === TorchState.On });\n this.torchState = state;\n } catch (error) {\n console.error('Failed to set torch', error);\n throw error;\n }\n }\n\n /**\n * Gets the current torch state.\n */\n async getTorch(): Promise<TorchState> {\n try {\n const result = await this.plugin.getTorch();\n this.torchState = result.enabled ? TorchState.On : TorchState.Off;\n return this.torchState;\n } catch (error) {\n console.error('Failed to get torch state', error);\n return this.torchState;\n }\n }\n\n /**\n * Toggles the torch state and returns the new value.\n */\n async toggleTorch(): Promise<TorchState> {\n const current = await this.getTorch();\n const next = current === TorchState.On ? TorchState.Off : TorchState.On;\n await this.setTorch(next);\n return next;\n }\n\n /**\n * Updates the camera preview rectangle dimensions\n * Call this method when the container size changes (e.g., orientation change)\n */\n async refresh(): Promise<void> {\n\n setTimeout(async () => {\n try {\n const containerElement = document.getElementById(this.options.containerId);\n if (!containerElement) {\n throw new Error(`Container with ID ${this.options.containerId} not found`);\n }\n const rect = containerElement.getBoundingClientRect();\n await this.plugin.updatePreviewRect({\n width: rect.width,\n height: rect.height,\n x: rect.x,\n y: rect.y\n });\n } catch (error) {\n console.error('Failed to update preview rect', error);\n throw error;\n }\n }, 100);\n }\n\n /**\n * Gets smart zoom levels that include physical camera switches\n * Returns an array of zoom levels and whether each is a physical camera\n */\n async getSmartZoomLevels(): Promise<{ level: number; isPhysicalCamera: boolean }[]> {\n const cameras = await this.getAvailableCameras();\n const zoomLevels: { level: number; isPhysicalCamera: boolean }[] = [];\n\n // Add ultrawide if available\n if (cameras.hasUltrawide && cameras.ultrawideZoomFactor) {\n zoomLevels.push({ level: cameras.ultrawideZoomFactor, isPhysicalCamera: true });\n }\n\n // Always add wide (1x)\n zoomLevels.push({ level: cameras.wideZoomFactor, isPhysicalCamera: true });\n\n // Add telephoto at its real zoom factor (derived from virtual device switch-over points)\n if (cameras.hasTelephoto && cameras.telephotoZoomFactor) {\n zoomLevels.push({ level: cameras.telephotoZoomFactor, isPhysicalCamera: true });\n }\n\n // Add intermediate and extended digital zoom levels\n const digitalZoomLevels = [2, 3, 5, 10];\n const zoomInfo = await this.getAvailableZoomLevels();\n for (const level of digitalZoomLevels) {\n // Only add if not already covered by a physical camera and within device capabilities\n const alreadyCovered = zoomLevels.some(z => Math.abs(z.level - level) < 0.1);\n if (!alreadyCovered && level > cameras.wideZoomFactor && level <= zoomInfo.maxZoom) {\n zoomLevels.push({ level, isPhysicalCamera: false });\n }\n }\n\n // Sort by zoom level\n zoomLevels.sort((a, b) => a.level - b.level);\n\n return zoomLevels;\n }\n\n /**\n * Performs smart zoom - switches physical cameras when appropriate\n */\n async performSmartZoom(targetZoom: number): Promise<void> {\n const cameras = await this.getAvailableCameras();\n \n // Determine if this zoom level should trigger a physical camera switch\n const physicalCameraZooms: number[] = [];\n if (cameras.hasUltrawide && cameras.ultrawideZoomFactor) {\n physicalCameraZooms.push(cameras.ultrawideZoomFactor);\n }\n physicalCameraZooms.push(cameras.wideZoomFactor);\n if (cameras.hasTelephoto && cameras.telephotoZoomFactor) {\n physicalCameraZooms.push(cameras.telephotoZoomFactor);\n }\n \n // Check if target zoom matches a physical camera\n const matchingPhysicalCamera = physicalCameraZooms.find(z => Math.abs(z - targetZoom) < 0.1);\n \n if (matchingPhysicalCamera) {\n // Switch to the physical camera\n await this.switchToPhysicalCamera(targetZoom);\n } else {\n // Use digital zoom\n await this.setZoom(targetZoom);\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { CameraImageData, CameraVideoData, CapturedImage, CapturedVideo, PhotoAddedEvent, PhotoUpdatedEvent, PhotoRemovedEvent, VideoAddedEvent, VideoRemovedEvent } from '../definitions';
|
|
2
|
+
/**
|
|
3
|
+
* Manages gallery operations and captured images
|
|
4
|
+
*/
|
|
5
|
+
export declare class GalleryController {
|
|
6
|
+
private galleryElement;
|
|
7
|
+
private images;
|
|
8
|
+
private videos;
|
|
9
|
+
private captureOrder;
|
|
10
|
+
private thumbnailStyle;
|
|
11
|
+
private onImageRemoved;
|
|
12
|
+
private onPhotoAdded?;
|
|
13
|
+
private onPhotoUpdated?;
|
|
14
|
+
private onPhotoRemoved?;
|
|
15
|
+
private onVideoAdded?;
|
|
16
|
+
private onVideoRemoved?;
|
|
17
|
+
private onMediaCountChanged?;
|
|
18
|
+
private enableEditing;
|
|
19
|
+
private markerJsLicenseKey?;
|
|
20
|
+
constructor(galleryElement: HTMLElement, thumbnailStyle?: {
|
|
21
|
+
width?: string;
|
|
22
|
+
height?: string;
|
|
23
|
+
}, onImageRemoved?: (images: CapturedImage[]) => void, onPhotoAdded?: (event: PhotoAddedEvent) => void, onPhotoUpdated?: (event: PhotoUpdatedEvent) => void, onPhotoRemoved?: (event: PhotoRemovedEvent) => void, onVideoAdded?: (event: VideoAddedEvent) => void, onVideoRemoved?: (event: VideoRemovedEvent) => void, onMediaCountChanged?: (totalCount: number) => void, enableEditing?: boolean, markerJsLicenseKey?: string);
|
|
24
|
+
private notifyMediaCountChanged;
|
|
25
|
+
/**
|
|
26
|
+
* Adds a new image to the gallery
|
|
27
|
+
*/
|
|
28
|
+
addImage(imageData: CameraImageData): void;
|
|
29
|
+
/**
|
|
30
|
+
* Removes an image from the gallery
|
|
31
|
+
*/
|
|
32
|
+
removeImage(imageId: string): void;
|
|
33
|
+
/**
|
|
34
|
+
* Adds a new video to the gallery
|
|
35
|
+
*/
|
|
36
|
+
addVideo(videoData: CameraVideoData): void;
|
|
37
|
+
/**
|
|
38
|
+
* Removes a video from the gallery
|
|
39
|
+
*/
|
|
40
|
+
removeVideo(videoId: string): void;
|
|
41
|
+
/**
|
|
42
|
+
* Clears all images from the gallery
|
|
43
|
+
*/
|
|
44
|
+
clearGallery(): void;
|
|
45
|
+
/**
|
|
46
|
+
* Gets all captured images
|
|
47
|
+
*/
|
|
48
|
+
getImages(): CapturedImage[];
|
|
49
|
+
/**
|
|
50
|
+
* Gets all captured videos
|
|
51
|
+
*/
|
|
52
|
+
getVideos(): CapturedVideo[];
|
|
53
|
+
/**
|
|
54
|
+
* Replaces an existing image's data (e.g. after annotation) and re-renders.
|
|
55
|
+
*/
|
|
56
|
+
updateImage(imageId: string, newData: CameraImageData): void;
|
|
57
|
+
/**
|
|
58
|
+
* Opens marker.js editor on the given image and replaces it on save.
|
|
59
|
+
*/
|
|
60
|
+
private handleEditImage;
|
|
61
|
+
/**
|
|
62
|
+
* Renders the gallery in chronological capture order
|
|
63
|
+
*/
|
|
64
|
+
private renderGallery;
|
|
65
|
+
private scrollToLatest;
|
|
66
|
+
}
|