@jaak.ai/stamps 2.0.0-dev.53 → 2.0.0-dev.55
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/README.md +660 -510
- package/dist/cjs/jaak-stamps.cjs.entry.js +158 -21
- package/dist/cjs/jaak-stamps.cjs.entry.js.map +1 -1
- package/dist/cjs/jaak-stamps.entry.cjs.js.map +1 -1
- package/dist/collection/services/CameraService.js +158 -21
- package/dist/collection/services/CameraService.js.map +1 -1
- package/dist/components/jaak-stamps.js +158 -21
- package/dist/components/jaak-stamps.js.map +1 -1
- package/dist/esm/jaak-stamps.entry.js +158 -21
- package/dist/esm/jaak-stamps.entry.js.map +1 -1
- package/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js +1 -1
- package/dist/jaak-stamps-webcomponent/jaak-stamps.entry.esm.js.map +1 -1
- package/dist/jaak-stamps-webcomponent/p-9ed19fa4.entry.js +2 -0
- package/dist/jaak-stamps-webcomponent/p-9ed19fa4.entry.js.map +1 -0
- package/dist/types/services/CameraService.d.ts +1 -0
- package/package.json +1 -1
- package/dist/jaak-stamps-webcomponent/p-8a00f7bd.entry.js +0 -2
- package/dist/jaak-stamps-webcomponent/p-8a00f7bd.entry.js.map +0 -1
|
@@ -199,6 +199,7 @@ class CameraService {
|
|
|
199
199
|
deviceType = 'desktop';
|
|
200
200
|
preferredCameraFacing = null;
|
|
201
201
|
preferredCamera = 'auto';
|
|
202
|
+
isManuallySelected = false;
|
|
202
203
|
constructor(logger, eventBus, preferredCamera = 'auto') {
|
|
203
204
|
this.logger = logger;
|
|
204
205
|
this.eventBus = eventBus;
|
|
@@ -245,6 +246,11 @@ class CameraService {
|
|
|
245
246
|
}))
|
|
246
247
|
});
|
|
247
248
|
this.setInitialCameraPreference();
|
|
249
|
+
this.logger.state('PREFERENCIA_INICIAL_APLICADA', {
|
|
250
|
+
selectedCameraId: this.selectedCameraId,
|
|
251
|
+
preferredCameraFacing: this.preferredCameraFacing,
|
|
252
|
+
preferredCamera: this.preferredCamera
|
|
253
|
+
});
|
|
248
254
|
this.eventBus.emit('camera-changed', this.selectedCameraId);
|
|
249
255
|
return this.availableCameras;
|
|
250
256
|
}
|
|
@@ -270,6 +276,7 @@ class CameraService {
|
|
|
270
276
|
}
|
|
271
277
|
this.selectedCameraId = cameraId;
|
|
272
278
|
this.updatePreferredFacing(camera);
|
|
279
|
+
this.isManuallySelected = true; // Mark as manually selected
|
|
273
280
|
this.savePreference();
|
|
274
281
|
this.eventBus.emit('camera-changed', cameraId);
|
|
275
282
|
}
|
|
@@ -277,12 +284,31 @@ class CameraService {
|
|
|
277
284
|
return this.preferredCameraFacing;
|
|
278
285
|
}
|
|
279
286
|
async setupCamera(constraints) {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
287
|
+
try {
|
|
288
|
+
const finalConstraints = constraints || await this.getMaxResolution();
|
|
289
|
+
const stream = await navigator.mediaDevices.getUserMedia({
|
|
290
|
+
video: finalConstraints,
|
|
291
|
+
audio: false
|
|
292
|
+
});
|
|
293
|
+
return stream;
|
|
294
|
+
}
|
|
295
|
+
catch (error) {
|
|
296
|
+
this.logger.error('Error en setupCamera, intentando con restricciones básicas:', error);
|
|
297
|
+
// Fallback to basic constraints if getMaxResolution fails
|
|
298
|
+
const basicConstraints = {
|
|
299
|
+
width: { ideal: 1280 },
|
|
300
|
+
height: { ideal: 720 }
|
|
301
|
+
};
|
|
302
|
+
// Only add facingMode if not on desktop to avoid OverconstrainedError
|
|
303
|
+
if (this.deviceType !== 'desktop' && this.preferredCameraFacing) {
|
|
304
|
+
basicConstraints.facingMode = this.preferredCameraFacing;
|
|
305
|
+
}
|
|
306
|
+
this.logger.state('USANDO_RESTRICCIONES_BASICAS', { constraints: basicConstraints });
|
|
307
|
+
return await navigator.mediaDevices.getUserMedia({
|
|
308
|
+
video: basicConstraints,
|
|
309
|
+
audio: false
|
|
310
|
+
});
|
|
311
|
+
}
|
|
286
312
|
}
|
|
287
313
|
async switchCamera(cameraId) {
|
|
288
314
|
const selectedCamera = this.availableCameras.find(cam => cam.deviceId === cameraId);
|
|
@@ -294,7 +320,8 @@ class CameraService {
|
|
|
294
320
|
await this.setSelectedCamera(cameraId);
|
|
295
321
|
this.logger.state('CAMARA_CAMBIADA', {
|
|
296
322
|
label: selectedCamera.label,
|
|
297
|
-
deviceId: selectedCamera.deviceId
|
|
323
|
+
deviceId: selectedCamera.deviceId,
|
|
324
|
+
isManuallySelected: this.isManuallySelected
|
|
298
325
|
});
|
|
299
326
|
}
|
|
300
327
|
async flipToNextCamera() {
|
|
@@ -376,6 +403,13 @@ class CameraService {
|
|
|
376
403
|
setInitialCameraPreference() {
|
|
377
404
|
if (this.availableCameras.length === 0)
|
|
378
405
|
return;
|
|
406
|
+
// Clear any existing localStorage preferences to ensure fresh start
|
|
407
|
+
localStorage.removeItem('jaak-stamps-camera-preference');
|
|
408
|
+
this.logger.state('APLICANDO_PREFERENCIA_INICIAL', {
|
|
409
|
+
preferredCamera: this.preferredCamera,
|
|
410
|
+
availableCamerasCount: this.availableCameras.length
|
|
411
|
+
});
|
|
412
|
+
this.isManuallySelected = false; // Reset manual selection flag
|
|
379
413
|
if (this.preferredCamera === 'front') {
|
|
380
414
|
this.selectFrontCamera();
|
|
381
415
|
}
|
|
@@ -388,23 +422,56 @@ class CameraService {
|
|
|
388
422
|
}
|
|
389
423
|
selectFrontCamera() {
|
|
390
424
|
this.preferredCameraFacing = 'user';
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
425
|
+
this.logger.state('BUSCANDO_CAMARA_FRONTAL', {
|
|
426
|
+
availableCameras: this.availableCameras.map(cam => ({
|
|
427
|
+
id: cam.deviceId,
|
|
428
|
+
label: cam.label
|
|
429
|
+
}))
|
|
430
|
+
});
|
|
431
|
+
const frontCamera = this.availableCameras.find(camera => {
|
|
432
|
+
const label = camera.label.toLowerCase();
|
|
433
|
+
return label.includes('front') ||
|
|
434
|
+
label.includes('user') ||
|
|
435
|
+
label.includes('selfie') ||
|
|
436
|
+
label.includes('frontal') ||
|
|
437
|
+
(!label.includes('back') && !label.includes('rear') && !label.includes('environment'));
|
|
438
|
+
});
|
|
439
|
+
// If not found, use the first camera (usually front on mobile)
|
|
395
440
|
this.selectedCameraId = frontCamera ? frontCamera.deviceId : this.availableCameras[0].deviceId;
|
|
396
441
|
this.logger.state('CAMARA_FRONTAL_SELECCIONADA', {
|
|
442
|
+
found: !!frontCamera,
|
|
397
443
|
label: frontCamera?.label || this.availableCameras[0].label,
|
|
398
444
|
deviceId: this.selectedCameraId
|
|
399
445
|
});
|
|
400
446
|
}
|
|
401
447
|
selectBackCamera() {
|
|
402
448
|
this.preferredCameraFacing = 'environment';
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
449
|
+
this.logger.state('BUSCANDO_CAMARA_TRASERA', {
|
|
450
|
+
availableCameras: this.availableCameras.map(cam => ({
|
|
451
|
+
id: cam.deviceId,
|
|
452
|
+
label: cam.label
|
|
453
|
+
}))
|
|
454
|
+
});
|
|
455
|
+
// Try to find rear camera with multiple detection methods
|
|
456
|
+
let backCamera = this.availableCameras.find(camera => {
|
|
457
|
+
const label = camera.label.toLowerCase();
|
|
458
|
+
return label.includes('back') ||
|
|
459
|
+
label.includes('rear') ||
|
|
460
|
+
label.includes('environment') ||
|
|
461
|
+
label.includes('trasera') ||
|
|
462
|
+
label.includes('posterior');
|
|
463
|
+
});
|
|
464
|
+
// If not found by label, try to use the last camera (usually rear on mobile)
|
|
465
|
+
if (!backCamera && this.availableCameras.length > 1) {
|
|
466
|
+
backCamera = this.availableCameras[this.availableCameras.length - 1];
|
|
467
|
+
this.logger.state('USANDO_ULTIMA_CAMARA_COMO_TRASERA', {
|
|
468
|
+
label: backCamera.label,
|
|
469
|
+
deviceId: backCamera.deviceId
|
|
470
|
+
});
|
|
471
|
+
}
|
|
406
472
|
this.selectedCameraId = backCamera ? backCamera.deviceId : this.availableCameras[0].deviceId;
|
|
407
473
|
this.logger.state('CAMARA_TRASERA_SELECCIONADA', {
|
|
474
|
+
found: !!backCamera,
|
|
408
475
|
label: backCamera?.label || this.availableCameras[0].label,
|
|
409
476
|
deviceId: this.selectedCameraId
|
|
410
477
|
});
|
|
@@ -415,8 +482,10 @@ class CameraService {
|
|
|
415
482
|
this.logger.state('CAMARA_AUTO_SELECCIONADA_MOBILE', { type: 'rear' });
|
|
416
483
|
}
|
|
417
484
|
else {
|
|
418
|
-
|
|
485
|
+
// For desktop, prefer front camera (usually built-in webcam)
|
|
486
|
+
this.selectFrontCamera();
|
|
419
487
|
this.logger.state('CAMARA_AUTO_SELECCIONADA_DESKTOP', {
|
|
488
|
+
type: 'front',
|
|
420
489
|
label: this.availableCameras[0].label,
|
|
421
490
|
deviceId: this.selectedCameraId
|
|
422
491
|
});
|
|
@@ -430,15 +499,60 @@ class CameraService {
|
|
|
430
499
|
}
|
|
431
500
|
async getMaxResolution() {
|
|
432
501
|
try {
|
|
502
|
+
// Ensure device type is detected before determining constraints
|
|
503
|
+
if (!this.deviceType || this.deviceType === 'desktop') {
|
|
504
|
+
await this.detectDeviceType();
|
|
505
|
+
}
|
|
433
506
|
const videoConstraints = {};
|
|
434
|
-
|
|
507
|
+
this.logger.state('CONFIGURANDO_CONSTRAINS_CAMARA', {
|
|
508
|
+
selectedCameraId: this.selectedCameraId,
|
|
509
|
+
preferredCameraFacing: this.preferredCameraFacing,
|
|
510
|
+
preferredCamera: this.preferredCamera,
|
|
511
|
+
deviceType: this.deviceType,
|
|
512
|
+
isManuallySelected: this.isManuallySelected
|
|
513
|
+
});
|
|
514
|
+
if (this.isManuallySelected && this.selectedCameraId) {
|
|
515
|
+
// When manually selected, use deviceId for exact camera selection
|
|
435
516
|
videoConstraints.deviceId = { exact: this.selectedCameraId };
|
|
517
|
+
this.logger.state('USANDO_CAMARA_MANUAL', {
|
|
518
|
+
deviceId: this.selectedCameraId
|
|
519
|
+
});
|
|
436
520
|
}
|
|
437
521
|
else if (this.preferredCameraFacing) {
|
|
438
|
-
|
|
522
|
+
// Use facingMode for initial preference-based selection
|
|
523
|
+
// Use 'ideal' instead of 'exact' to avoid OverconstrainedError on desktop
|
|
524
|
+
const facingConstraint = this.deviceType === 'desktop'
|
|
525
|
+
? { ideal: this.preferredCameraFacing }
|
|
526
|
+
: { exact: this.preferredCameraFacing };
|
|
527
|
+
videoConstraints.facingMode = facingConstraint;
|
|
528
|
+
this.logger.state('USANDO_FACING_CONSTRAINT', {
|
|
529
|
+
facingMode: this.preferredCameraFacing,
|
|
530
|
+
constraintType: this.deviceType === 'desktop' ? 'ideal' : 'exact'
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
else if (this.selectedCameraId) {
|
|
534
|
+
videoConstraints.deviceId = { exact: this.selectedCameraId };
|
|
535
|
+
this.logger.state('USANDO_CAMARA_SELECCIONADA', {
|
|
536
|
+
deviceId: this.selectedCameraId
|
|
537
|
+
});
|
|
439
538
|
}
|
|
440
539
|
else {
|
|
441
|
-
|
|
540
|
+
// Use preferredCamera setting to determine default facing mode
|
|
541
|
+
if (this.preferredCamera === 'front') {
|
|
542
|
+
videoConstraints.facingMode = "user";
|
|
543
|
+
}
|
|
544
|
+
else if (this.preferredCamera === 'back') {
|
|
545
|
+
videoConstraints.facingMode = "environment";
|
|
546
|
+
}
|
|
547
|
+
else {
|
|
548
|
+
// Auto mode: use environment for mobile/tablet, user for desktop
|
|
549
|
+
videoConstraints.facingMode = (this.deviceType === 'mobile' || this.deviceType === 'tablet') ? "environment" : "user";
|
|
550
|
+
}
|
|
551
|
+
this.logger.state('USANDO_PREFERENCIA_CONFIGURADA', {
|
|
552
|
+
facingMode: videoConstraints.facingMode,
|
|
553
|
+
preferredCamera: this.preferredCamera,
|
|
554
|
+
deviceType: this.deviceType
|
|
555
|
+
});
|
|
442
556
|
}
|
|
443
557
|
const tempStream = await navigator.mediaDevices.getUserMedia({
|
|
444
558
|
video: videoConstraints
|
|
@@ -470,6 +584,10 @@ class CameraService {
|
|
|
470
584
|
}
|
|
471
585
|
catch (err) {
|
|
472
586
|
this.logger.warn('No se pudieron obtener capacidades de cámara, usando configuración de respaldo');
|
|
587
|
+
// Ensure device type is detected before determining constraints
|
|
588
|
+
if (!this.deviceType || this.deviceType === 'desktop') {
|
|
589
|
+
await this.detectDeviceType();
|
|
590
|
+
}
|
|
473
591
|
const isTablet = /iPad|Android/i.test(navigator.userAgent) && window.innerWidth >= 768;
|
|
474
592
|
const fallbackConstraints = {
|
|
475
593
|
width: { ideal: isTablet ? 1280 : 1920 },
|
|
@@ -477,14 +595,33 @@ class CameraService {
|
|
|
477
595
|
};
|
|
478
596
|
// Apply basic focus settings even for fallback
|
|
479
597
|
this.applyBasicFocusSettings(fallbackConstraints);
|
|
480
|
-
if (this.selectedCameraId) {
|
|
598
|
+
if (this.isManuallySelected && this.selectedCameraId) {
|
|
599
|
+
// When manually selected, use deviceId for exact camera selection
|
|
481
600
|
fallbackConstraints.deviceId = { exact: this.selectedCameraId };
|
|
482
601
|
}
|
|
483
602
|
else if (this.preferredCameraFacing) {
|
|
484
|
-
|
|
603
|
+
// Use facingMode for initial preference-based selection
|
|
604
|
+
// Use 'ideal' instead of 'exact' to avoid OverconstrainedError on desktop
|
|
605
|
+
const facingConstraint = this.deviceType === 'desktop'
|
|
606
|
+
? { ideal: this.preferredCameraFacing }
|
|
607
|
+
: { exact: this.preferredCameraFacing };
|
|
608
|
+
fallbackConstraints.facingMode = facingConstraint;
|
|
609
|
+
}
|
|
610
|
+
else if (this.selectedCameraId) {
|
|
611
|
+
fallbackConstraints.deviceId = { exact: this.selectedCameraId };
|
|
485
612
|
}
|
|
486
613
|
else {
|
|
487
|
-
|
|
614
|
+
// Use preferredCamera setting to determine default facing mode
|
|
615
|
+
if (this.preferredCamera === 'front') {
|
|
616
|
+
fallbackConstraints.facingMode = "user";
|
|
617
|
+
}
|
|
618
|
+
else if (this.preferredCamera === 'back') {
|
|
619
|
+
fallbackConstraints.facingMode = "environment";
|
|
620
|
+
}
|
|
621
|
+
else {
|
|
622
|
+
// Auto mode: use environment for mobile/tablet, user for desktop
|
|
623
|
+
fallbackConstraints.facingMode = (this.deviceType === 'mobile' || this.deviceType === 'tablet') ? "environment" : "user";
|
|
624
|
+
}
|
|
488
625
|
}
|
|
489
626
|
return fallbackConstraints;
|
|
490
627
|
}
|