@ -1,24 +1,104 @@ 
			
		
	
		
			
				
					< template >  
			
		
	
		
			
				
					  <!--  CONTENT  -- >  
			
		
	
		
			
				
					  < section  id = "Content"  class = "relativew-[100vw] h-[100vh]" >  
			
		
	
		
			
				
					  < section  id = "Content"  class = "relative  w-[100vw] h-[100vh]" >  
			
		
	
		
			
				
					    < div  
			
		
	
		
			
				
					      class = "absolute inset-x-0 bottom-0 bg-black/50 p-6 pb-[calc(env(safe-area-inset-bottom)+1.5rem)] "  
			
		
	
		
			
				
					      class = "p-6 bg-white w-full max-w-[calc((100vh-env(safe-area-inset-top)-env(safe-area-inset-bottom))*0.4)] mx-auto "  
			
		
	
		
			
				
					    >  
			
		
	
		
			
				
					      < p  class = "text-center text-white mb-3" >  
			
		
	
		
			
				
					        Point  your  camera  at  a  TimeSafari  contact  QR  code  to  scan  it  
			
		
	
		
			
				
					        automatically .  
			
		
	
		
			
				
					      < / p >  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					      < p  v-if ="error" class="text-center text-rose-300 mb-3" > {{  error  }} < / p >  
			
		
	
		
			
				
					      < div  class = "mb-4" >  
			
		
	
		
			
				
					        < h1  class = "text-xl text-center font-semibold relative" >  
			
		
	
		
			
				
					          <!--  Back  -- >  
			
		
	
		
			
				
					          < a  
			
		
	
		
			
				
					            class = "text-lg text-center px-2 py-1 absolute -left-2 -top-1"  
			
		
	
		
			
				
					            @ click = "handleBack"  
			
		
	
		
			
				
					          >  
			
		
	
		
			
				
					            < font -awesome  icon = "chevron-left"  class = "fa-fw"  / >  
			
		
	
		
			
				
					          < / a >  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					          <!--  Quick  Help  -- >  
			
		
	
		
			
				
					          < a  
			
		
	
		
			
				
					            class = "text-xl text-center text-blue-500 px-2 py-1 absolute -right-2 -top-1"  
			
		
	
		
			
				
					            @ click = "toastQRCodeHelp()"  
			
		
	
		
			
				
					          >  
			
		
	
		
			
				
					            < font -awesome  icon = "circle-question"  class = "fa-fw"  / >  
			
		
	
		
			
				
					          < / a >  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					          Share  Contact  Info  
			
		
	
		
			
				
					        < / h1 >  
			
		
	
		
			
				
					      < / div >  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					      < div  class = "flex justify-center items-center" >  
			
		
	
		
			
				
					      < div  
			
		
	
		
			
				
					        v - if = "!givenName"  
			
		
	
		
			
				
					        class = "bg-amber-200 text-amber-900 border-amber-500 border-dashed border text-center rounded-md overflow-hidden px-4 py-3 mt-4"  
			
		
	
		
			
				
					      >  
			
		
	
		
			
				
					        < p  class = "mb-2" >  
			
		
	
		
			
				
					          < b > Note : < / b >  your  identity  currently  does  < b > not < / b >  include  a  name .  
			
		
	
		
			
				
					        < / p >  
			
		
	
		
			
				
					        < button  
			
		
	
		
			
				
					          class = "text-center text-slate-600 leading-none bg-white p-2 rounded-full drop-shadow-lg"  
			
		
	
		
			
				
					          @ click = "handleBack"  
			
		
	
		
			
				
					          class = "inline-block text-md uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-4 py-2 rounded-md "  
			
		
	
		
			
				
					          @ click = "openUserNameDialog "  
			
		
	
		
			
				
					        >  
			
		
	
		
			
				
					          < font -awesome  icon = "xmark"  class = "size-6" > < / f o n t - a w e s o m e >  
			
		
	
		
			
				
					          Set  Your  Name  
			
		
	
		
			
				
					        < / button >  
			
		
	
		
			
				
					      < / div >  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					      < UserNameDialog  ref = "userNameDialog"  / >  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					      < div  
			
		
	
		
			
				
					        v - if = "activeDid && activeDid.startsWith(ETHR_DID_PREFIX)"  
			
		
	
		
			
				
					        class = "block w-full max-w-[calc((100vh-env(safe-area-inset-top)-env(safe-area-inset-bottom))*0.4)] mx-auto mt-4"  
			
		
	
		
			
				
					        @ click = "onCopyUrlToClipboard()"  
			
		
	
		
			
				
					      >  
			
		
	
		
			
				
					        <!--  
			
		
	
		
			
				
					          Play  with  display  options :  https : / / q r - c o d e - s t y l i n g . c o m /  
			
		
	
		
			
				
					          See  docs :  https : / / w w w . n p m j s . c o m / p a c k a g e / q r - c o d e - g e n e r a t o r - v u e 3  
			
		
	
		
			
				
					        -- >  
			
		
	
		
			
				
					        < QRCodeVue3  
			
		
	
		
			
				
					          : value = "qrValue"  
			
		
	
		
			
				
					          : width = "606"  
			
		
	
		
			
				
					          : height = "606"  
			
		
	
		
			
				
					          : corners - square - options = "{ type: 'square' }"  
			
		
	
		
			
				
					          : dots - options = "{ type: 'square', color: '#000' }"  
			
		
	
		
			
				
					        / >  
			
		
	
		
			
				
					      < / div >  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					      < div  v -else -if = " activeDid "  class = "text-center mt-4" >  
			
		
	
		
			
				
					        <!--  Not  an  ETHR  DID  so  force  them  to  paste  it .  ( Passkey  Peer  DIDs  are  too  big . )  -- >  
			
		
	
		
			
				
					        < span  class = "text-blue-500"  @click ="onCopyDidToClipboard()" >  
			
		
	
		
			
				
					          Click  here  to  copy  your  DID  to  your  clipboard .  
			
		
	
		
			
				
					        < / span >  
			
		
	
		
			
				
					        < span >  
			
		
	
		
			
				
					          Then  give  it  to  them  so  they  can  paste  it  in  their  list  of  People .  
			
		
	
		
			
				
					        < / span >  
			
		
	
		
			
				
					      < / div >  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					      < div  v -else  class = "text-center mt-4" >  
			
		
	
		
			
				
					        You  have  no  identitifiers  yet ,  so  
			
		
	
		
			
				
					        < router -link  
			
		
	
		
			
				
					          : to = "{ name: 'start' }"  
			
		
	
		
			
				
					          class = "bg-blue-500 text-white px-1.5 py-1 rounded-md"  
			
		
	
		
			
				
					        >  
			
		
	
		
			
				
					          create  your  identifier .  
			
		
	
		
			
				
					        < / r o u t e r - l i n k >  
			
		
	
		
			
				
					        < br  / >  
			
		
	
		
			
				
					        If  you  don 't do that first, these contacts won' t  see  your  activity .  
			
		
	
		
			
				
					      < / div >  
			
		
	
		
			
				
					    < / div >  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    < div  
			
		
	
		
			
				
					      class = "relative w-full max-w-[calc((100vh-env(safe-area-inset-top)-env(safe-area-inset-bottom))*0.4)] mx-auto border border-dashed border-white mt-8 aspect-square"  
			
		
	
		
			
				
					    >  
			
		
	
		
			
				
					      < p  
			
		
	
		
			
				
					        class = "absolute top-0 left-0 right-0 bg-black bg-opacity-50 text-white text-sm text-center py-2 z-10"  
			
		
	
		
			
				
					      >  
			
		
	
		
			
				
					        Position  QR  code  in  the  frame  
			
		
	
		
			
				
					      < / p >  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					      < p  
			
		
	
		
			
				
					        v - if = "error"  
			
		
	
		
			
				
					        class = "absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 text-sm text-center py-2 z-20 text-rose-400"  
			
		
	
		
			
				
					      >  
			
		
	
		
			
				
					        { {  error  } }  
			
		
	
		
			
				
					      < / p >  
			
		
	
		
			
				
					    < / div >  
			
		
	
		
			
				
					  < / section >  
			
		
	
		
			
				
					< / template >  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -33,18 +113,29 @@ import { NotificationIface } from "../constants/app"; 
			
		
	
		
			
				
					import  {  db  }  from  "../db/index" ;  
			
		
	
		
			
				
					import  {  Contact  }  from  "../db/tables/contacts" ;  
			
		
	
		
			
				
					import  {  getContactJwtFromJwtUrl  }  from  "../libs/crypto" ;  
			
		
	
		
			
				
					import  {  decodeEndorserJwt  }  from  "../libs/crypto/vc" ;  
			
		
	
		
			
				
					import  {  decodeEndorserJwt ,  ETHR_DID_PREFIX }  from  "../libs/crypto/vc" ;  
			
		
	
		
			
				
					import  {  retrieveSettingsForActiveAccount  }  from  "../db/index" ;  
			
		
	
		
			
				
					import  {  setVisibilityUtil  }  from  "../libs/endorserServer" ;  
			
		
	
		
			
				
					import  {  useClipboard  }  from  "@vueuse/core" ;  
			
		
	
		
			
				
					import  QRCodeVue3  from  "qr-code-generator-vue3" ;  
			
		
	
		
			
				
					import  UserNameDialog  from  "../components/UserNameDialog.vue" ;  
			
		
	
		
			
				
					import  {  generateEndorserJwtUrlForAccount  }  from  "../libs/endorserServer" ;  
			
		
	
		
			
				
					import  {  retrieveAccountMetadata  }  from  "../libs/util" ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					interface  QRScanResult  {  
			
		
	
		
			
				
					  rawValue ? :  string ;  
			
		
	
		
			
				
					  barcode ? :  string ;  
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					interface  IUserNameDialog  {  
			
		
	
		
			
				
					  open :  ( callback :  ( name :  string )  =>  void )  =>  void ;  
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					@ Component ( {  
			
		
	
		
			
				
					  components :  {  
			
		
	
		
			
				
					    QuickNav ,  
			
		
	
		
			
				
					    QRCodeVue3 ,  
			
		
	
		
			
				
					    UserNameDialog ,  
			
		
	
		
			
				
					  } ,  
			
		
	
		
			
				
					} )  
			
		
	
		
			
				
					export  default  class  ContactQRScan  extends  Vue  {  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -55,11 +146,14 @@ export default class ContactQRScan extends Vue { 
			
		
	
		
			
				
					  error :  string  |  null  =  null ;  
			
		
	
		
			
				
					  activeDid  =  "" ;  
			
		
	
		
			
				
					  apiServer  =  "" ;  
			
		
	
		
			
				
					  givenName  =  "" ;  
			
		
	
		
			
				
					  qrValue  =  "" ;  
			
		
	
		
			
				
					  ETHR_DID_PREFIX  =  ETHR_DID_PREFIX ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  / /   A d d   n e w   p r o p e r t i e s   t o   t r a c k   s c a n n i n g   s t a t e  
			
		
	
		
			
				
					  private  lastScannedValue :  string  =  "" ;  
			
		
	
		
			
				
					  private  lastScanTime :  number  =  0 ;  
			
		
	
		
			
				
					  private  readonly  SCAN_DEBOUNCE_MS  =  2 000;  / /   P r e v e n t   d u p l i c a t e   s c a n s   w i t h i n   2   s e c o n d s  
			
		
	
		
			
				
					  private  readonly  SCAN_DEBOUNCE_MS  =  5 000;  / /   I n c r e a s e d   f r o m   2 0 0 0   t o   5 0 0 0 m s   t o   b e t t e r   h a n d l e   m o b i l e   s c a n n i n g  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  / /   A d d   c l e a n u p   t r a c k i n g  
			
		
	
		
			
				
					  private  isCleaningUp  =  false ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -70,6 +164,21 @@ export default class ContactQRScan extends Vue { 
			
		
	
		
			
				
					      const  settings  =  await  retrieveSettingsForActiveAccount ( ) ;  
			
		
	
		
			
				
					      this . activeDid  =  settings . activeDid  ||  "" ;  
			
		
	
		
			
				
					      this . apiServer  =  settings . apiServer  ||  "" ;  
			
		
	
		
			
				
					      this . givenName  =  settings . firstName  ||  "" ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					      const  account  =  await  retrieveAccountMetadata ( this . activeDid ) ;  
			
		
	
		
			
				
					      if  ( account )  {  
			
		
	
		
			
				
					        const  name  =  
			
		
	
		
			
				
					          ( settings . firstName  ||  "" )  +  
			
		
	
		
			
				
					          ( settings . lastName  ?  `   ${ settings . lastName } `  :  "" ) ;  
			
		
	
		
			
				
					        this . qrValue  =  await  generateEndorserJwtUrlForAccount (  
			
		
	
		
			
				
					          account ,  
			
		
	
		
			
				
					          ! ! settings . isRegistered ,  
			
		
	
		
			
				
					          name ,  
			
		
	
		
			
				
					          settings . profileImageUrl  ||  "" ,  
			
		
	
		
			
				
					          false ,  
			
		
	
		
			
				
					        ) ;  
			
		
	
		
			
				
					      }  
			
		
	
		
			
				
					    }  catch  ( error )  {  
			
		
	
		
			
				
					      logger . error ( "Error initializing component:" ,  {  
			
		
	
		
			
				
					        error :  error  instanceof  Error  ?  error . message  :  String ( error ) ,  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -270,14 +379,12 @@ export default class ContactQRScan extends Vue { 
			
		
	
		
			
				
					        notes :  contactInfo . notes  ||  "" ,  
			
		
	
		
			
				
					      } ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					      / /   A d d   c o n t a c t   a n d   s t o p   s c a n n i n g  
			
		
	
		
			
				
					      / /   A d d   c o n t a c t   b u t   k e e p   s c a n n i n g  
			
		
	
		
			
				
					      logger . info ( "Adding new contact to database:" ,  {  
			
		
	
		
			
				
					        did :  contact . did ,  
			
		
	
		
			
				
					        name :  contact . name ,  
			
		
	
		
			
				
					      } ) ;  
			
		
	
		
			
				
					      await  this . addNewContact ( contact ) ;  
			
		
	
		
			
				
					      await  this . stopScanning ( ) ;  
			
		
	
		
			
				
					      this . $router . back ( ) ;  / /   R e t u r n   t o   p r e v i o u s   v i e w   a f t e r   s u c c e s s f u l   s c a n  
			
		
	
		
			
				
					    }  catch  ( error )  {  
			
		
	
		
			
				
					      logger . error ( "Error processing contact QR code:" ,  {  
			
		
	
		
			
				
					        error :  error  instanceof  Error  ?  error . message  :  String ( error ) ,  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -420,6 +527,56 @@ export default class ContactQRScan extends Vue { 
			
		
	
		
			
				
					    await  this . cleanupScanner ( ) ;  
			
		
	
		
			
				
					    this . $router . back ( ) ;  
			
		
	
		
			
				
					  }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  toastQRCodeHelp ( )  {  
			
		
	
		
			
				
					    this . $notify (  
			
		
	
		
			
				
					      {  
			
		
	
		
			
				
					        group :  "alert" ,  
			
		
	
		
			
				
					        type :  "info" ,  
			
		
	
		
			
				
					        title :  "QR Code Help" ,  
			
		
	
		
			
				
					        text :  "Click the QR code to copy your contact info to your clipboard." ,  
			
		
	
		
			
				
					      } ,  
			
		
	
		
			
				
					      5000 ,  
			
		
	
		
			
				
					    ) ;  
			
		
	
		
			
				
					  }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  onCopyUrlToClipboard ( )  {  
			
		
	
		
			
				
					    useClipboard ( )  
			
		
	
		
			
				
					      . copy ( this . qrValue )  
			
		
	
		
			
				
					      . then ( ( )  =>  {  
			
		
	
		
			
				
					        this . $notify (  
			
		
	
		
			
				
					          {  
			
		
	
		
			
				
					            group :  "alert" ,  
			
		
	
		
			
				
					            type :  "toast" ,  
			
		
	
		
			
				
					            title :  "Copied" ,  
			
		
	
		
			
				
					            text :  "Contact URL was copied to clipboard." ,  
			
		
	
		
			
				
					          } ,  
			
		
	
		
			
				
					          2000 ,  
			
		
	
		
			
				
					        ) ;  
			
		
	
		
			
				
					      } ) ;  
			
		
	
		
			
				
					  }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  onCopyDidToClipboard ( )  {  
			
		
	
		
			
				
					    useClipboard ( )  
			
		
	
		
			
				
					      . copy ( this . activeDid )  
			
		
	
		
			
				
					      . then ( ( )  =>  {  
			
		
	
		
			
				
					        this . $notify (  
			
		
	
		
			
				
					          {  
			
		
	
		
			
				
					            group :  "alert" ,  
			
		
	
		
			
				
					            type :  "info" ,  
			
		
	
		
			
				
					            title :  "Copied" ,  
			
		
	
		
			
				
					            text :  "Your DID was copied to the clipboard. Have them paste it in the box on their 'People' screen to add you." ,  
			
		
	
		
			
				
					          } ,  
			
		
	
		
			
				
					          5000 ,  
			
		
	
		
			
				
					        ) ;  
			
		
	
		
			
				
					      } ) ;  
			
		
	
		
			
				
					  }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  openUserNameDialog ( )  {  
			
		
	
		
			
				
					    ( this . $refs . userNameDialog  as  IUserNameDialog ) . open ( ( name :  string )  =>  {  
			
		
	
		
			
				
					      this . givenName  =  name ;  
			
		
	
		
			
				
					    } ) ;  
			
		
	
		
			
				
					  }  
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					< / script >