|
@ -144,6 +144,7 @@ |
|
|
<qrcode-stream |
|
|
<qrcode-stream |
|
|
v-if="useQRReader" |
|
|
v-if="useQRReader" |
|
|
:camera="preferredCamera" |
|
|
:camera="preferredCamera" |
|
|
|
|
|
class="qr-scanner" |
|
|
@decode="onDecode" |
|
|
@decode="onDecode" |
|
|
@init="onInit" |
|
|
@init="onInit" |
|
|
@detect="onDetect" |
|
|
@detect="onDetect" |
|
@ -255,6 +256,9 @@ export default class ContactQRScanShow extends Vue { |
|
|
private isCleaningUp = false; |
|
|
private isCleaningUp = false; |
|
|
private isMounted = false; |
|
|
private isMounted = false; |
|
|
|
|
|
|
|
|
|
|
|
// Add property to track if we're on desktop |
|
|
|
|
|
private isDesktop = false; |
|
|
|
|
|
|
|
|
async created() { |
|
|
async created() { |
|
|
try { |
|
|
try { |
|
|
const settings = await retrieveSettingsForActiveAccount(); |
|
|
const settings = await retrieveSettingsForActiveAccount(); |
|
@ -714,10 +718,19 @@ export default class ContactQRScanShow extends Vue { |
|
|
// Lifecycle hooks |
|
|
// Lifecycle hooks |
|
|
mounted() { |
|
|
mounted() { |
|
|
this.isMounted = true; |
|
|
this.isMounted = true; |
|
|
|
|
|
this.isDesktop = this.detectDesktopBrowser(); |
|
|
document.addEventListener("pause", this.handleAppPause); |
|
|
document.addEventListener("pause", this.handleAppPause); |
|
|
document.addEventListener("resume", this.handleAppResume); |
|
|
document.addEventListener("resume", this.handleAppResume); |
|
|
// Start scanning automatically when view is loaded |
|
|
// Start scanning automatically when view is loaded |
|
|
this.startScanning(); |
|
|
this.startScanning(); |
|
|
|
|
|
|
|
|
|
|
|
// Apply mirroring after a short delay to ensure video element is ready |
|
|
|
|
|
setTimeout(() => { |
|
|
|
|
|
const videoElement = document.querySelector('.qr-scanner video') as HTMLVideoElement; |
|
|
|
|
|
if (videoElement) { |
|
|
|
|
|
videoElement.style.transform = 'scaleX(-1)'; |
|
|
|
|
|
} |
|
|
|
|
|
}, 1000); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
beforeDestroy() { |
|
|
beforeDestroy() { |
|
@ -926,6 +939,22 @@ export default class ContactQRScanShow extends Vue { |
|
|
stack: error.stack, |
|
|
stack: error.stack, |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Add method to detect desktop browser |
|
|
|
|
|
private detectDesktopBrowser(): boolean { |
|
|
|
|
|
const userAgent = navigator.userAgent.toLowerCase(); |
|
|
|
|
|
return !/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(userAgent); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Update the computed property for camera mirroring |
|
|
|
|
|
get shouldMirrorCamera(): boolean { |
|
|
|
|
|
// On desktop, always mirror the webcam |
|
|
|
|
|
if (this.isDesktop) { |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
// On mobile, mirror only for front-facing camera |
|
|
|
|
|
return this.preferredCamera === "user"; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
</script> |
|
|
</script> |
|
|
|
|
|
|
|
@ -933,4 +962,18 @@ export default class ContactQRScanShow extends Vue { |
|
|
.aspect-square { |
|
|
.aspect-square { |
|
|
aspect-ratio: 1 / 1; |
|
|
aspect-ratio: 1 / 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Update styles for camera mirroring */ |
|
|
|
|
|
:deep(.qr-scanner) { |
|
|
|
|
|
position: relative; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
:deep(.qr-scanner video) { |
|
|
|
|
|
transform: scaleX(-1); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Ensure the canvas for QR detection is not mirrored */ |
|
|
|
|
|
:deep(.qr-scanner canvas) { |
|
|
|
|
|
transform: none; |
|
|
|
|
|
} |
|
|
</style> |
|
|
</style> |
|
|