|  |  | @ -135,11 +135,11 @@ | 
			
		
	
		
			
				
					|  |  |  |           </button> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |           <button v-if="contact.registered" class="tooltip"> | 
			
		
	
		
			
				
					|  |  |  |             <span class="tooltiptext">They are registered</span> | 
			
		
	
		
			
				
					|  |  |  |             <span class="tooltiptext">Registered</span> | 
			
		
	
		
			
				
					|  |  |  |             <fa icon="person-circle-check" class="text-slate-900 fa-fw ml-1" /> | 
			
		
	
		
			
				
					|  |  |  |           </button> | 
			
		
	
		
			
				
					|  |  |  |           <button v-else @click="register(contact)" class="tooltip"> | 
			
		
	
		
			
				
					|  |  |  |             <span class="tooltiptext">They may not be registered</span> | 
			
		
	
		
			
				
					|  |  |  |             <span class="tooltiptext">Registration Unknown</span> | 
			
		
	
		
			
				
					|  |  |  |             <fa | 
			
		
	
		
			
				
					|  |  |  |               icon="person-circle-question" | 
			
		
	
		
			
				
					|  |  |  |               class="text-slate-900 fa-fw ml-1" | 
			
		
	
	
		
			
				
					|  |  | @ -170,7 +170,7 @@ | 
			
		
	
		
			
				
					|  |  |  |                 </span> | 
			
		
	
		
			
				
					|  |  |  |                 <button | 
			
		
	
		
			
				
					|  |  |  |                   class="text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md mb-6" | 
			
		
	
		
			
				
					|  |  |  |                   @click="onClickAddGive(identity.did, contact.did)" | 
			
		
	
		
			
				
					|  |  |  |                   @click="onClickAddGive(activeDid, contact.did)" | 
			
		
	
		
			
				
					|  |  |  |                 > | 
			
		
	
		
			
				
					|  |  |  |                   + | 
			
		
	
		
			
				
					|  |  |  |                 </button> | 
			
		
	
	
		
			
				
					|  |  | @ -192,7 +192,7 @@ | 
			
		
	
		
			
				
					|  |  |  |                 </span> | 
			
		
	
		
			
				
					|  |  |  |                 <button | 
			
		
	
		
			
				
					|  |  |  |                   class="text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md mb-6" | 
			
		
	
		
			
				
					|  |  |  |                   @click="onClickAddGive(contact.did, identity.did)" | 
			
		
	
		
			
				
					|  |  |  |                   @click="onClickAddGive(contact.did, activeDid)" | 
			
		
	
		
			
				
					|  |  |  |                 > | 
			
		
	
		
			
				
					|  |  |  |                   + | 
			
		
	
		
			
				
					|  |  |  |                 </button> | 
			
		
	
	
		
			
				
					|  |  | @ -251,6 +251,7 @@ const Buffer = require("buffer/").Buffer; | 
			
		
	
		
			
				
					|  |  |  |   components: {}, | 
			
		
	
		
			
				
					|  |  |  | }) | 
			
		
	
		
			
				
					|  |  |  | export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |   activeDid = ""; | 
			
		
	
		
			
				
					|  |  |  |   contacts: Array<Contact> = []; | 
			
		
	
		
			
				
					|  |  |  |   contactInput = ""; | 
			
		
	
		
			
				
					|  |  |  |   // { "did:...": concatenated-descriptions } entry for each contact | 
			
		
	
	
		
			
				
					|  |  | @ -267,19 +268,16 @@ export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |   givenToMeUnconfirmed: Record<string, number> = {}; | 
			
		
	
		
			
				
					|  |  |  |   hourDescriptionInput = ""; | 
			
		
	
		
			
				
					|  |  |  |   hourInput = "0"; | 
			
		
	
		
			
				
					|  |  |  |   identity: IIdentifier | null = null; | 
			
		
	
		
			
				
					|  |  |  |   showGiveNumbers = false; | 
			
		
	
		
			
				
					|  |  |  |   showGiveTotals = true; | 
			
		
	
		
			
				
					|  |  |  |   showGiveConfirmed = true; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   // 'created' hook runs when the Vue instance is first created | 
			
		
	
		
			
				
					|  |  |  |   async created() { | 
			
		
	
		
			
				
					|  |  |  |     await accountsDB.open(); | 
			
		
	
		
			
				
					|  |  |  |     const accounts = await accountsDB.accounts.toArray(); | 
			
		
	
		
			
				
					|  |  |  |     this.identity = JSON.parse(accounts[0].identity); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     await db.open(); | 
			
		
	
		
			
				
					|  |  |  |     const settings = await db.settings.get(MASTER_SETTINGS_KEY); | 
			
		
	
		
			
				
					|  |  |  |     this.activeDid = settings?.activeDid || ""; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     this.showGiveNumbers = !!settings?.showContactGivesInline; | 
			
		
	
		
			
				
					|  |  |  |     if (this.showGiveNumbers) { | 
			
		
	
		
			
				
					|  |  |  |       this.loadGives(); | 
			
		
	
	
		
			
				
					|  |  | @ -292,7 +290,12 @@ export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   async loadGives() { | 
			
		
	
		
			
				
					|  |  |  |     if (!this.identity) { | 
			
		
	
		
			
				
					|  |  |  |     await accountsDB.open(); | 
			
		
	
		
			
				
					|  |  |  |     const accounts = await accountsDB.accounts.toArray(); | 
			
		
	
		
			
				
					|  |  |  |     const account = R.find((acc) => acc.did === this.activeDid, accounts); | 
			
		
	
		
			
				
					|  |  |  |     const identity = JSON.parse(account?.identity || "undefined"); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     if (!identity) { | 
			
		
	
		
			
				
					|  |  |  |       console.error( | 
			
		
	
		
			
				
					|  |  |  |         "Attempted to load Give records with no identity available." | 
			
		
	
		
			
				
					|  |  |  |       ); | 
			
		
	
	
		
			
				
					|  |  | @ -306,8 +309,8 @@ export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |       const url = | 
			
		
	
		
			
				
					|  |  |  |         endorserApiServer + | 
			
		
	
		
			
				
					|  |  |  |         "/api/v2/report/gives?agentDid=" + | 
			
		
	
		
			
				
					|  |  |  |         encodeURIComponent(this.identity?.did); | 
			
		
	
		
			
				
					|  |  |  |       const token = await accessToken(this.identity); | 
			
		
	
		
			
				
					|  |  |  |         encodeURIComponent(identity.did); | 
			
		
	
		
			
				
					|  |  |  |       const token = await accessToken(identity); | 
			
		
	
		
			
				
					|  |  |  |       const headers = { | 
			
		
	
		
			
				
					|  |  |  |         "Content-Type": "application/json", | 
			
		
	
		
			
				
					|  |  |  |         Authorization: "Bearer " + token, | 
			
		
	
	
		
			
				
					|  |  | @ -361,8 +364,8 @@ export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |       const url = | 
			
		
	
		
			
				
					|  |  |  |         endorserApiServer + | 
			
		
	
		
			
				
					|  |  |  |         "/api/v2/report/gives?recipientDid=" + | 
			
		
	
		
			
				
					|  |  |  |         encodeURIComponent(this.identity.did); | 
			
		
	
		
			
				
					|  |  |  |       const token = await accessToken(this.identity); | 
			
		
	
		
			
				
					|  |  |  |         encodeURIComponent(identity.did); | 
			
		
	
		
			
				
					|  |  |  |       const token = await accessToken(identity); | 
			
		
	
		
			
				
					|  |  |  |       const headers = { | 
			
		
	
		
			
				
					|  |  |  |         "Content-Type": "application/json", | 
			
		
	
		
			
				
					|  |  |  |         Authorization: "Bearer " + token, | 
			
		
	
	
		
			
				
					|  |  | @ -464,7 +467,9 @@ export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |     ) { | 
			
		
	
		
			
				
					|  |  |  |       await accountsDB.open(); | 
			
		
	
		
			
				
					|  |  |  |       const accounts = await accountsDB.accounts.toArray(); | 
			
		
	
		
			
				
					|  |  |  |       const identity = JSON.parse(accounts[0].identity); | 
			
		
	
		
			
				
					|  |  |  |       const account = R.find((acc) => acc.did === this.activeDid, accounts); | 
			
		
	
		
			
				
					|  |  |  |       const identity = JSON.parse(account?.identity || "undefined"); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |       // Make a claim | 
			
		
	
		
			
				
					|  |  |  |       const vcClaim: RegisterVerifiableCredential = { | 
			
		
	
		
			
				
					|  |  |  |         "@context": "https://schema.org", | 
			
		
	
	
		
			
				
					|  |  | @ -544,7 +549,9 @@ export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |       (visibility ? "canSeeMe" : "cannotSeeMe"); | 
			
		
	
		
			
				
					|  |  |  |     await accountsDB.open(); | 
			
		
	
		
			
				
					|  |  |  |     const accounts = await accountsDB.accounts.toArray(); | 
			
		
	
		
			
				
					|  |  |  |     const identity = JSON.parse(accounts[0].identity); | 
			
		
	
		
			
				
					|  |  |  |     const account = R.find((acc) => acc.did === this.activeDid, accounts); | 
			
		
	
		
			
				
					|  |  |  |     const identity = JSON.parse(account?.identity || "undefined"); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     const token = await accessToken(identity); | 
			
		
	
		
			
				
					|  |  |  |     const headers = { | 
			
		
	
		
			
				
					|  |  |  |       "Content-Type": "application/json", | 
			
		
	
	
		
			
				
					|  |  | @ -582,7 +589,9 @@ export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |       encodeURIComponent(contact.did); | 
			
		
	
		
			
				
					|  |  |  |     await accountsDB.open(); | 
			
		
	
		
			
				
					|  |  |  |     const accounts = await accountsDB.accounts.toArray(); | 
			
		
	
		
			
				
					|  |  |  |     const identity = JSON.parse(accounts[0].identity); | 
			
		
	
		
			
				
					|  |  |  |     const account = R.find((acc) => acc.did === this.activeDid, accounts); | 
			
		
	
		
			
				
					|  |  |  |     const identity = JSON.parse(account?.identity || "undefined"); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     const token = await accessToken(identity); | 
			
		
	
		
			
				
					|  |  |  |     const headers = { | 
			
		
	
		
			
				
					|  |  |  |       "Content-Type": "application/json", | 
			
		
	
	
		
			
				
					|  |  | @ -635,8 +644,13 @@ export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   async onClickAddGive(fromDid: string, toDid: string): Promise<void> { | 
			
		
	
		
			
				
					|  |  |  |     await accountsDB.open(); | 
			
		
	
		
			
				
					|  |  |  |     const accounts = await accountsDB.accounts.toArray(); | 
			
		
	
		
			
				
					|  |  |  |     const account = R.find((acc) => acc.did === this.activeDid, accounts); | 
			
		
	
		
			
				
					|  |  |  |     const identity = JSON.parse(account?.identity || "undefined"); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     // if they have unconfirmed amounts, ask to confirm those first | 
			
		
	
		
			
				
					|  |  |  |     if (toDid == this.identity?.did && this.givenToMeUnconfirmed[fromDid] > 0) { | 
			
		
	
		
			
				
					|  |  |  |     if (toDid == identity?.did && this.givenToMeUnconfirmed[fromDid] > 0) { | 
			
		
	
		
			
				
					|  |  |  |       if ( | 
			
		
	
		
			
				
					|  |  |  |         confirm( | 
			
		
	
		
			
				
					|  |  |  |           "There are " + | 
			
		
	
	
		
			
				
					|  |  | @ -660,14 +674,14 @@ export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |       this.alertTitle = "Input Error"; | 
			
		
	
		
			
				
					|  |  |  |       this.alertMessage = "Giving 0 hours does nothing."; | 
			
		
	
		
			
				
					|  |  |  |       this.isAlertVisible = true; | 
			
		
	
		
			
				
					|  |  |  |     } else if (!this.identity) { | 
			
		
	
		
			
				
					|  |  |  |     } else if (!identity) { | 
			
		
	
		
			
				
					|  |  |  |       this.alertTitle = "Status Error"; | 
			
		
	
		
			
				
					|  |  |  |       this.alertMessage = "No identity is available."; | 
			
		
	
		
			
				
					|  |  |  |       this.isAlertVisible = true; | 
			
		
	
		
			
				
					|  |  |  |     } else { | 
			
		
	
		
			
				
					|  |  |  |       // ask to confirm amount | 
			
		
	
		
			
				
					|  |  |  |       let toFrom; | 
			
		
	
		
			
				
					|  |  |  |       if (fromDid == this.identity?.did) { | 
			
		
	
		
			
				
					|  |  |  |       if (fromDid == identity?.did) { | 
			
		
	
		
			
				
					|  |  |  |         toFrom = "from you to " + this.nameForDid(this.contacts, toDid); | 
			
		
	
		
			
				
					|  |  |  |       } else { | 
			
		
	
		
			
				
					|  |  |  |         toFrom = "from " + this.nameForDid(this.contacts, fromDid) + " to you"; | 
			
		
	
	
		
			
				
					|  |  | @ -689,7 +703,7 @@ export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |         ) | 
			
		
	
		
			
				
					|  |  |  |       ) { | 
			
		
	
		
			
				
					|  |  |  |         this.createAndSubmitGive( | 
			
		
	
		
			
				
					|  |  |  |           this.identity, | 
			
		
	
		
			
				
					|  |  |  |           identity, | 
			
		
	
		
			
				
					|  |  |  |           fromDid, | 
			
		
	
		
			
				
					|  |  |  |           toDid, | 
			
		
	
		
			
				
					|  |  |  |           parseFloat(this.hourInput), | 
			
		
	
	
		
			
				
					|  |  | 
 |