@jaak.ai/stamps 2.0.0-dev.53 → 2.0.0-dev.54

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