@ -298,14 +298,14 @@ export default class QRScannerDialog extends Vue {
errorMessage = "" ;
errorMessage = "" ;
created ( ) {
created ( ) {
console . log ( '[QRScannerDialog] created' ) ;
logger . log ( "[QRScannerDialog] created" ) ;
console . log ( '[QRScannerDialog] Props received:' , {
logger . log ( "[QRScannerDialog] Props received:" , {
onScan : typeof this . onScan ,
onScan : typeof this . onScan ,
onError : typeof this . onError ,
onError : typeof this . onError ,
options : this . options ,
options : this . options ,
onClose : typeof this . onClose ,
onClose : typeof this . onClose ,
} ) ;
} ) ;
console . log ( '[QRScannerDialog] Initial state:' , {
logger . log ( "[QRScannerDialog] Initial state:" , {
visible : this . visible ,
visible : this . visible ,
error : this . error ,
error : this . error ,
useQRReader : this . useQRReader ,
useQRReader : this . useQRReader ,
@ -336,61 +336,69 @@ export default class QRScannerDialog extends Vue {
}
}
mounted ( ) {
mounted ( ) {
console . log ( '[QRScannerDialog] mounted' ) ;
logger . log ( "[QRScannerDialog] mounted" ) ;
/ / T i m e r t o w a r n i f n o Q R c o d e d e t e c t e d a f t e r 1 0 s e c o n d s
/ / T i m e r t o w a r n i f n o Q R c o d e d e t e c t e d a f t e r 1 0 s e c o n d s
this . _scanTimeout = setTimeout ( ( ) => {
this . _scanTimeout = setTimeout ( ( ) => {
if ( ! this . isScanning ) {
if ( ! this . isScanning ) {
console . warn ( '[QRScannerDialog] No QR code detected after 10 seconds' ) ;
logger . warn ( "[QRScannerDialog] No QR code detected after 10 seconds" ) ;
}
}
} , 10000 ) ;
} , 10000 ) ;
/ / P e r i o d i c t i m e r t o l o g w a i t i n g s t a t u s e v e r y 5 s e c o n d s
/ / P e r i o d i c t i m e r t o l o g w a i t i n g s t a t u s e v e r y 5 s e c o n d s
this . _waitingInterval = setInterval ( ( ) => {
this . _waitingInterval = setInterval ( ( ) => {
if ( ! this . isScanning && this . cameraStatus === 'Active' ) {
if ( ! this . isScanning && this . cameraStatus === "Active" ) {
console . log ( '[QRScannerDialog] Still waiting for QR code detection...' ) ;
logger . log ( "[QRScannerDialog] Still waiting for QR code detection..." ) ;
}
}
} , 5000 ) ;
} , 5000 ) ;
console . log ( '[QRScannerDialog] Waiting interval started' ) ;
logger . log ( "[QRScannerDialog] Waiting interval started" ) ;
}
}
beforeUnmount ( ) {
beforeUnmount ( ) {
if ( this . _scanTimeout ) {
if ( this . _scanTimeout ) {
clearTimeout ( this . _scanTimeout ) ;
clearTimeout ( this . _scanTimeout ) ;
console . log ( '[QRScannerDialog] Scan timeout cleared' ) ;
logger . log ( "[QRScannerDialog] Scan timeout cleared" ) ;
}
}
if ( this . _waitingInterval ) {
if ( this . _waitingInterval ) {
clearInterval ( this . _waitingInterval ) ;
clearInterval ( this . _waitingInterval ) ;
console . log ( '[QRScannerDialog] Waiting interval cleared' ) ;
logger . log ( "[QRScannerDialog] Waiting interval cleared" ) ;
}
}
console . log ( '[QRScannerDialog] beforeUnmount' ) ;
logger . log ( "[QRScannerDialog] beforeUnmount" ) ;
}
}
async onInit ( promise : Promise < void > ) : Promise < void > {
async onInit ( promise : Promise < void > ) : Promise < void > {
console . log ( '[QRScannerDialog] onInit called' ) ;
logger . log ( "[QRScannerDialog] onInit called" ) ;
if ( this . isNativePlatform ) {
if ( this . isNativePlatform ) {
logger . log ( "Closing QR dialog on native platform" ) ;
logger . log ( "Closing QR dialog on native platform" ) ;
this . $nextTick ( ( ) => this . close ( ) ) ;
this . $nextTick ( ( ) => this . close ( ) ) ;
return ;
return ;
}
}
this . isInitializing = true ;
this . isInitializing = true ;
console . log ( '[QRScannerDialog] isInitializing set to' , this . isInitializing ) ;
logger . log ( "[QRScannerDialog] isInitializing set to" , this . isInitializing ) ;
this . error = null ;
this . error = null ;
this . initializationStatus = "Checking camera access..." ;
this . initializationStatus = "Checking camera access..." ;
console . log ( '[QRScannerDialog] initializationStatus set to' , this . initializationStatus ) ;
logger . log (
"[QRScannerDialog] initializationStatus set to" ,
this . initializationStatus ,
) ;
try {
try {
if ( ! navigator . mediaDevices ) {
if ( ! navigator . mediaDevices ) {
console . log ( '[QRScannerDialog] Camera API not available' ) ;
logger . log ( "[QRScannerDialog] Camera API not available" ) ;
throw new Error (
throw new Error (
"Camera API not available. Please ensure you're using HTTPS." ,
"Camera API not available. Please ensure you're using HTTPS." ,
) ;
) ;
}
}
const devices = await navigator . mediaDevices . enumerateDevices ( ) ;
const devices = await navigator . mediaDevices . enumerateDevices ( ) ;
const videoDevices = devices . filter ( ( device ) => device . kind === "videoinput" ) ;
const videoDevices = devices . filter (
console . log ( '[QRScannerDialog] videoDevices found:' , videoDevices . length ) ;
( device ) => device . kind === "videoinput" ,
) ;
logger . log ( "[QRScannerDialog] videoDevices found:" , videoDevices . length ) ;
if ( videoDevices . length === 0 ) {
if ( videoDevices . length === 0 ) {
throw new Error ( "No camera found on this device" ) ;
throw new Error ( "No camera found on this device" ) ;
}
}
this . initializationStatus = "Requesting camera permission..." ;
this . initializationStatus = "Requesting camera permission..." ;
console . log ( '[QRScannerDialog] initializationStatus set to' , this . initializationStatus ) ;
logger . log (
"[QRScannerDialog] initializationStatus set to" ,
this . initializationStatus ,
) ;
try {
try {
const stream = await navigator . mediaDevices . getUserMedia ( {
const stream = await navigator . mediaDevices . getUserMedia ( {
video : {
video : {
@ -401,10 +409,17 @@ export default class QRScannerDialog extends Vue {
} ) ;
} ) ;
stream . getTracks ( ) . forEach ( ( track ) => track . stop ( ) ) ;
stream . getTracks ( ) . forEach ( ( track ) => track . stop ( ) ) ;
this . initializationStatus = "Camera permission granted..." ;
this . initializationStatus = "Camera permission granted..." ;
console . log ( '[QRScannerDialog] initializationStatus set to' , this . initializationStatus ) ;
logger . log (
"[QRScannerDialog] initializationStatus set to" ,
this . initializationStatus ,
) ;
} catch ( permissionError ) {
} catch ( permissionError ) {
const error = permissionError as Error ;
const error = permissionError as Error ;
console . log ( '[QRScannerDialog] Camera permission error:' , error . name , error . message ) ;
logger . log (
"[QRScannerDialog] Camera permission error:" ,
error . name ,
error . message ,
) ;
if (
if (
error . name === "NotAllowedError" ||
error . name === "NotAllowedError" ||
error . name === "PermissionDeniedError"
error . name === "PermissionDeniedError"
@ -429,67 +444,94 @@ export default class QRScannerDialog extends Vue {
}
}
}
}
this . initializationStatus = "Starting QR scanner..." ;
this . initializationStatus = "Starting QR scanner..." ;
console . log ( '[QRScannerDialog] initializationStatus set to' , this . initializationStatus ) ;
logger . log (
"[QRScannerDialog] initializationStatus set to" ,
this . initializationStatus ,
) ;
await promise ;
await promise ;
this . isInitializing = false ;
this . isInitializing = false ;
this . cameraStatus = "Ready" ;
this . cameraStatus = "Ready" ;
console . log ( '[QRScannerDialog] QR scanner initialized successfully' ) ;
logger . log ( "[QRScannerDialog] QR scanner initialized successfully" ) ;
console . log ( '[QRScannerDialog] cameraStatus set to' , this . cameraStatus ) ;
logger . log ( "[QRScannerDialog] cameraStatus set to" , this . cameraStatus ) ;
} catch ( error ) {
} catch ( error ) {
const wrappedError = error instanceof Error ? error : new Error ( String ( error ) ) ;
const wrappedError =
error instanceof Error ? error : new Error ( String ( error ) ) ;
this . error = wrappedError . message ;
this . error = wrappedError . message ;
this . cameraStatus = "Error" ;
this . cameraStatus = "Error" ;
console . log ( '[QRScannerDialog] Error initializing QR scanner:' , wrappedError . message ) ;
logger . log (
console . log ( '[QRScannerDialog] cameraStatus set to' , this . cameraStatus ) ;
"[QRScannerDialog] Error initializing QR scanner:" ,
wrappedError . message ,
) ;
logger . log ( "[QRScannerDialog] cameraStatus set to" , this . cameraStatus ) ;
if ( this . onError ) {
if ( this . onError ) {
this . onError ( wrappedError ) ;
this . onError ( wrappedError ) ;
}
}
} finally {
} finally {
this . isInitializing = false ;
this . isInitializing = false ;
console . log ( '[QRScannerDialog] isInitializing set to' , this . isInitializing ) ;
logger . log (
"[QRScannerDialog] isInitializing set to" ,
this . isInitializing ,
) ;
}
}
}
}
onCameraOn ( ) : void {
onCameraOn ( ) : void {
this . cameraStatus = "Active" ;
this . cameraStatus = "Active" ;
console . log ( '[QRScannerDialog] Camera turned on successfully' ) ;
logger . log ( "[QRScannerDialog] Camera turned on successfully" ) ;
console . log ( '[QRScannerDialog] cameraStatus set to' , this . cameraStatus ) ;
logger . log ( "[QRScannerDialog] cameraStatus set to" , this . cameraStatus ) ;
}
}
onCameraOff ( ) : void {
onCameraOff ( ) : void {
this . cameraStatus = "Off" ;
this . cameraStatus = "Off" ;
console . log ( '[QRScannerDialog] Camera turned off' ) ;
logger . log ( "[QRScannerDialog] Camera turned off" ) ;
console . log ( '[QRScannerDialog] cameraStatus set to' , this . cameraStatus ) ;
logger . log ( "[QRScannerDialog] cameraStatus set to" , this . cameraStatus ) ;
}
}
onDetect ( result : DetectionResult | Promise < DetectionResult > ) : void {
onDetect ( result : DetectionResult | Promise < DetectionResult > ) : void {
const ts = new Date ( ) . toISOString ( ) ;
const ts = new Date ( ) . toISOString ( ) ;
console . log ( ` [QRScannerDialog] onDetect called at ${ ts } with ` , result ) ;
logger . log ( ` [QRScannerDialog] onDetect called at ${ ts } with ` , result ) ;
this . isScanning = true ;
this . isScanning = true ;
this . cameraStatus = "Detecting" ;
this . cameraStatus = "Detecting" ;
console . log ( '[QRScannerDialog] isScanning set to' , this . isScanning ) ;
logger . log ( "[QRScannerDialog] isScanning set to" , this . isScanning ) ;
console . log ( '[QRScannerDialog] cameraStatus set to' , this . cameraStatus ) ;
logger . log ( "[QRScannerDialog] cameraStatus set to" , this . cameraStatus ) ;
const processResult = ( detection : DetectionResult | DetectionResult [ ] ) => {
const processResult = ( detection : DetectionResult | DetectionResult [ ] ) => {
try {
try {
console . log ( ` [QRScannerDialog] onDetect exit at ${ new Date ( ) . toISOString ( ) } with detection: ` , detection ) ;
logger . log (
` [QRScannerDialog] onDetect exit at ${ new Date ( ) . toISOString ( ) } with detection: ` ,
detection ,
) ;
/ / F a l l b a c k : I f d e t e c t i o n i s a n a r r a y , c h e c k t h e f i r s t e l e m e n t
/ / F a l l b a c k : I f d e t e c t i o n i s a n a r r a y , c h e c k t h e f i r s t e l e m e n t
let rawValue : string | undefined ;
let rawValue : string | undefined ;
if ( Array . isArray ( detection ) && detection . length > 0 && 'rawValue' in detection [ 0 ] ) {
if (
Array . isArray ( detection ) &&
detection . length > 0 &&
"rawValue" in detection [ 0 ]
) {
rawValue = detection [ 0 ] . rawValue ;
rawValue = detection [ 0 ] . rawValue ;
} else if ( detection && typeof detection === 'object' && 'rawValue' in detection && detection . rawValue ) {
} else if (
rawValue = ( detection as any ) . rawValue ;
detection &&
typeof detection === "object" &&
"rawValue" in detection &&
detection . rawValue
) {
rawValue = ( detection as unknown ) . rawValue ;
}
}
if ( rawValue ) {
if ( rawValue ) {
console . log ( '[QRScannerDialog] Fallback: Detected rawValue, treating as scan:' , rawValue ) ;
logger . log (
"[QRScannerDialog] Fallback: Detected rawValue, treating as scan:" ,
rawValue ,
) ;
this . isInitializing = false ;
this . isInitializing = false ;
this . initializationStatus = 'QR code captured!' ;
this . initializationStatus = "QR code captured!" ;
this . onScan ( rawValue ) ;
this . onScan ( rawValue ) ;
try {
try {
console . log ( '[QRScannerDialog] About to call close() after scan' ) ;
logger . log ( "[QRScannerDialog] About to call close() after scan" ) ;
this . close ( ) ;
this . close ( ) ;
console . log ( '[QRScannerDialog] close() called successfully after scan' ) ;
logger . log (
"[QRScannerDialog] close() called successfully after scan" ,
) ;
} catch ( err ) {
} catch ( err ) {
console . error ( '[QRScannerDialog] Error calling close():' , err ) ;
logger . error ( "[QRScannerDialog] Error calling close():" , err ) ;
}
}
}
}
} catch ( error ) {
} catch ( error ) {
@ -497,8 +539,8 @@ export default class QRScannerDialog extends Vue {
} finally {
} finally {
this . isScanning = false ;
this . isScanning = false ;
this . cameraStatus = "Active" ;
this . cameraStatus = "Active" ;
console . log ( '[QRScannerDialog] isScanning set to' , this . isScanning ) ;
logger . log ( "[QRScannerDialog] isScanning set to" , this . isScanning ) ;
console . log ( '[QRScannerDialog] cameraStatus set to' , this . cameraStatus ) ;
logger . log ( "[QRScannerDialog] cameraStatus set to" , this . cameraStatus ) ;
}
}
} ;
} ;
if ( result instanceof Promise ) {
if ( result instanceof Promise ) {
@ -508,8 +550,11 @@ export default class QRScannerDialog extends Vue {
. finally ( ( ) => {
. finally ( ( ) => {
this . isScanning = false ;
this . isScanning = false ;
this . cameraStatus = "Active" ;
this . cameraStatus = "Active" ;
console . log ( '[QRScannerDialog] isScanning set to' , this . isScanning ) ;
logger . log ( "[QRScannerDialog] isScanning set to" , this . isScanning ) ;
console . log ( '[QRScannerDialog] cameraStatus set to' , this . cameraStatus ) ;
logger . log (
"[QRScannerDialog] cameraStatus set to" ,
this . cameraStatus ,
) ;
} ) ;
} ) ;
} else {
} else {
processResult ( result ) ;
processResult ( result ) ;
@ -517,11 +562,12 @@ export default class QRScannerDialog extends Vue {
}
}
private handleError ( error : unknown ) : void {
private handleError ( error : unknown ) : void {
const wrappedError = error instanceof Error ? error : new Error ( String ( error ) ) ;
const wrappedError =
error instanceof Error ? error : new Error ( String ( error ) ) ;
this . error = wrappedError . message ;
this . error = wrappedError . message ;
this . cameraStatus = "Error" ;
this . cameraStatus = "Error" ;
console . log ( '[QRScannerDialog] handleError:' , wrappedError . message ) ;
logger . log ( "[QRScannerDialog] handleError:" , wrappedError . message ) ;
console . log ( '[QRScannerDialog] cameraStatus set to' , this . cameraStatus ) ;
logger . log ( "[QRScannerDialog] cameraStatus set to" , this . cameraStatus ) ;
if ( this . onError ) {
if ( this . onError ) {
this . onError ( wrappedError ) ;
this . onError ( wrappedError ) ;
}
}
@ -529,14 +575,24 @@ export default class QRScannerDialog extends Vue {
onDecode ( result : string ) : void {
onDecode ( result : string ) : void {
const ts = new Date ( ) . toISOString ( ) ;
const ts = new Date ( ) . toISOString ( ) ;
console . log ( ` [QRScannerDialog] onDecode called at ${ ts } with result: ` , result ) ;
logger . log (
` [QRScannerDialog] onDecode called at ${ ts } with result: ` ,
result ,
) ;
try {
try {
this . isInitializing = false ;
this . isInitializing = false ;
this . initializationStatus = 'QR code captured!' ;
this . initializationStatus = "QR code captured!" ;
console . log ( '[QRScannerDialog] UI state updated after scan: isInitializing set to' , this . isInitializing , ', initializationStatus set to' , this . initializationStatus ) ;
logger . log (
"[QRScannerDialog] UI state updated after scan: isInitializing set to" ,
this . isInitializing ,
", initializationStatus set to" ,
this . initializationStatus ,
) ;
this . onScan ( result ) ;
this . onScan ( result ) ;
this . close ( ) ;
this . close ( ) ;
console . log ( ` [QRScannerDialog] onDecode exit at ${ new Date ( ) . toISOString ( ) } ` ) ;
logger . log (
` [QRScannerDialog] onDecode exit at ${ new Date ( ) . toISOString ( ) } ` ,
) ;
} catch ( error ) {
} catch ( error ) {
this . handleError ( error ) ;
this . handleError ( error ) ;
}
}
@ -544,77 +600,95 @@ export default class QRScannerDialog extends Vue {
toggleCamera ( ) : void {
toggleCamera ( ) : void {
const prevCamera = this . preferredCamera ;
const prevCamera = this . preferredCamera ;
this . preferredCamera = this . preferredCamera === "user" ? "environment" : "user" ;
this . preferredCamera =
console . log ( '[QRScannerDialog] toggleCamera from' , prevCamera , 'to' , this . preferredCamera ) ;
this . preferredCamera === "user" ? "environment" : "user" ;
console . log ( '[QRScannerDialog] preferredCamera set to' , this . preferredCamera ) ;
logger . log (
"[QRScannerDialog] toggleCamera from" ,
prevCamera ,
"to" ,
this . preferredCamera ,
) ;
logger . log (
"[QRScannerDialog] preferredCamera set to" ,
this . preferredCamera ,
) ;
}
}
retryScanning ( ) : void {
retryScanning ( ) : void {
console . log ( '[QRScannerDialog] retryScanning called' ) ;
logger . log ( "[QRScannerDialog] retryScanning called" ) ;
this . error = null ;
this . error = null ;
this . isInitializing = true ;
this . isInitializing = true ;
console . log ( '[QRScannerDialog] isInitializing set to' , this . isInitializing ) ;
logger . log ( "[QRScannerDialog] isInitializing set to" , this . isInitializing ) ;
console . log ( '[QRScannerDialog] Scanning re-initialized' ) ;
logger . log ( "[QRScannerDialog] Scanning re-initialized" ) ;
}
}
close = async ( ) : Promise < void > => {
close = async ( ) : Promise < void > => {
console . log ( '[QRScannerDialog] close called' ) ;
logger . log ( "[QRScannerDialog] close called" ) ;
this . visible = false ;
this . visible = false ;
console . log ( '[QRScannerDialog] visible set to' , this . visible ) ;
logger . log ( "[QRScannerDialog] visible set to" , this . visible ) ;
/ / N o t i f y p a r e n t / s e r v i c e
/ / N o t i f y p a r e n t / s e r v i c e
if ( typeof this . onClose === 'function' ) {
if ( typeof this . onClose === "function" ) {
console . log ( '[QRScannerDialog] Calling onClose prop' ) ;
logger . log ( "[QRScannerDialog] Calling onClose prop" ) ;
this . onClose ( ) ;
this . onClose ( ) ;
}
}
await this . $nextTick ( ) ;
await this . $nextTick ( ) ;
if ( this . $el && this . $el . parentNode ) {
if ( this . $el && this . $el . parentNode ) {
this . $el . parentNode . removeChild ( this . $el ) ;
this . $el . parentNode . removeChild ( this . $el ) ;
console . log ( '[QRScannerDialog] Dialog element removed from DOM' ) ;
logger . log ( "[QRScannerDialog] Dialog element removed from DOM" ) ;
} else {
} else {
console . log ( '[QRScannerDialog] Dialog element NOT removed from DOM' ) ;
logger . log ( "[QRScannerDialog] Dialog element NOT removed from DOM" ) ;
}
}
}
} ;
onScanDetect ( promisedResult ) {
onScanDetect ( promisedResult ) {
const ts = new Date ( ) . toISOString ( ) ;
const ts = new Date ( ) . toISOString ( ) ;
console . log ( ` [QRScannerDialog] onScanDetect called at ${ ts } with ` , promisedResult ) ;
logger . log (
` [QRScannerDialog] onScanDetect called at ${ ts } with ` ,
promisedResult ,
) ;
promisedResult
promisedResult
. then ( ( result ) => {
. then ( ( result ) => {
console . log ( ` [QRScannerDialog] onScanDetect exit at ${ new Date ( ) . toISOString ( ) } with result: ` , result ) ;
logger . log (
` [QRScannerDialog] onScanDetect exit at ${ new Date ( ) . toISOString ( ) } with result: ` ,
result ,
) ;
this . onScan ( result ) ;
this . onScan ( result ) ;
} )
} )
. catch ( ( error ) => {
. catch ( ( error ) => {
console . error ( ` [QRScannerDialog] onScanDetect error at ${ new Date ( ) . toISOString ( ) } : ` , error ) ;
logger . error (
this . errorMessage = error . message || 'Scan error' ;
` [QRScannerDialog] onScanDetect error at ${ new Date ( ) . toISOString ( ) } : ` ,
error ,
) ;
this . errorMessage = error . message || "Scan error" ;
if ( this . onError ) this . onError ( error ) ;
if ( this . onError ) this . onError ( error ) ;
} ) ;
} ) ;
}
}
onScanError ( error ) {
onScanError ( error ) {
const ts = new Date ( ) . toISOString ( ) ;
const ts = new Date ( ) . toISOString ( ) ;
console . error ( ` [QRScannerDialog] onScanError called at ${ ts } : ` , error ) ;
logger . error ( ` [QRScannerDialog] onScanError called at ${ ts } : ` , error ) ;
this . errorMessage = error . message || 'Camera error' ;
this . errorMessage = error . message || "Camera error" ;
if ( this . onError ) this . onError ( error ) ;
if ( this . onError ) this . onError ( error ) ;
}
}
async startMobileScan ( ) {
async startMobileScan ( ) {
try {
try {
console . log ( '[QRScannerDialog] startMobileScan called' ) ;
logger . log ( "[QRScannerDialog] startMobileScan called" ) ;
const scanner = QRScannerFactory . getInstance ( ) ;
const scanner = QRScannerFactory . getInstance ( ) ;
await scanner . startScan ( ) ;
await scanner . startScan ( ) ;
} catch ( error ) {
} catch ( error ) {
console . error ( '[QRScannerDialog] Error starting mobile scan:' , error ) ;
logger . error ( "[QRScannerDialog] Error starting mobile scan:" , error ) ;
if ( this . onError ) this . onError ( error ) ;
if ( this . onError ) this . onError ( error ) ;
}
}
}
}
async copyLogs ( ) {
async copyLogs ( ) {
console . log ( '[QRScannerDialog] copyLogs called' ) ;
logger . log ( "[QRScannerDialog] copyLogs called" ) ;
try {
try {
await navigator . clipboard . writeText ( logCollector . getLogs ( ) ) ;
await navigator . clipboard . writeText ( logCollector . getLogs ( ) ) ;
alert ( 'Logs copied to clipboard!' ) ;
alert ( "Logs copied to clipboard!" ) ;
} catch ( e ) {
} catch ( e ) {
alert ( 'Failed to copy logs: ' + ( e instanceof Error ? e . message : e ) ) ;
alert ( "Failed to copy logs: " + ( e instanceof Error ? e . message : e ) ) ;
}
}
}
}
}
}