|  |  | @ -43,6 +43,7 @@ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     <div class="flex justify-between" v-if="showGiveNumbers"> | 
			
		
	
		
			
				
					|  |  |  |       <div class="w-full text-right"> | 
			
		
	
		
			
				
					|  |  |  |         <!-- | 
			
		
	
		
			
				
					|  |  |  |         Hours to Add: | 
			
		
	
		
			
				
					|  |  |  |         <input | 
			
		
	
		
			
				
					|  |  |  |           class="border rounded border-slate-400 w-24 text-right" | 
			
		
	
	
		
			
				
					|  |  | @ -57,30 +58,29 @@ | 
			
		
	
		
			
				
					|  |  |  |           placeholder="Description" | 
			
		
	
		
			
				
					|  |  |  |           v-model="hourDescriptionInput" | 
			
		
	
		
			
				
					|  |  |  |         /> | 
			
		
	
		
			
				
					|  |  |  |         <br /> | 
			
		
	
		
			
				
					|  |  |  |         --> | 
			
		
	
		
			
				
					|  |  |  |         In the following, only the most recent hours are included. To see more, | 
			
		
	
		
			
				
					|  |  |  |         click | 
			
		
	
		
			
				
					|  |  |  |         <span | 
			
		
	
		
			
				
					|  |  |  |           class="text-sm uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1 py-1 rounded-md" | 
			
		
	
		
			
				
					|  |  |  |         > | 
			
		
	
		
			
				
					|  |  |  |           <fa icon="file-lines" class="fa-fw" /> | 
			
		
	
		
			
				
					|  |  |  |         </span> | 
			
		
	
		
			
				
					|  |  |  |         <br /> | 
			
		
	
		
			
				
					|  |  |  |         <button | 
			
		
	
		
			
				
					|  |  |  |           href="" | 
			
		
	
		
			
				
					|  |  |  |           class="text-center text-md text-white px-1.5 py-2 rounded-md mb-6" | 
			
		
	
		
			
				
					|  |  |  |           class="text-center text-md text-white px-1.5 py-2 rounded-md mt-1" | 
			
		
	
		
			
				
					|  |  |  |           v-bind:class="showGiveAmountsClassNames()" | 
			
		
	
		
			
				
					|  |  |  |           @click="toggleShowGiveTotals()" | 
			
		
	
		
			
				
					|  |  |  |         > | 
			
		
	
		
			
				
					|  |  |  |           {{ | 
			
		
	
		
			
				
					|  |  |  |             showGiveTotals | 
			
		
	
		
			
				
					|  |  |  |               ? "Total" | 
			
		
	
		
			
				
					|  |  |  |               ? "Showing Total" | 
			
		
	
		
			
				
					|  |  |  |               : showGiveConfirmed | 
			
		
	
		
			
				
					|  |  |  |                 ? "Confirmed" | 
			
		
	
		
			
				
					|  |  |  |                 : "Unconfirmed" | 
			
		
	
		
			
				
					|  |  |  |           }} | 
			
		
	
		
			
				
					|  |  |  |         </button> | 
			
		
	
		
			
				
					|  |  |  |         <br /> | 
			
		
	
		
			
				
					|  |  |  |         (Only most recent hours included. To see more, click | 
			
		
	
		
			
				
					|  |  |  |         <span | 
			
		
	
		
			
				
					|  |  |  |           class="text-sm uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1 py-1 rounded-md" | 
			
		
	
		
			
				
					|  |  |  |         > | 
			
		
	
		
			
				
					|  |  |  |           <fa icon="file-lines" class="fa-fw" /> | 
			
		
	
		
			
				
					|  |  |  |         </span> | 
			
		
	
		
			
				
					|  |  |  |         ) | 
			
		
	
		
			
				
					|  |  |  |       </div> | 
			
		
	
		
			
				
					|  |  |  |     </div> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -189,10 +189,11 @@ | 
			
		
	
		
			
				
					|  |  |  |             > | 
			
		
	
		
			
				
					|  |  |  |               <button | 
			
		
	
		
			
				
					|  |  |  |                 class="text-sm 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-2 py-1.5 rounded-l-md" | 
			
		
	
		
			
				
					|  |  |  |                 @click="onClickAddGive(activeDid, contact.did)" | 
			
		
	
		
			
				
					|  |  |  |                 @click="showGiftedDialog(activeDid, contact.did)" | 
			
		
	
		
			
				
					|  |  |  |                 :title="givenByMeDescriptions[contact.did] || ''" | 
			
		
	
		
			
				
					|  |  |  |               > | 
			
		
	
		
			
				
					|  |  |  |                 To: | 
			
		
	
		
			
				
					|  |  |  |                 <br /> | 
			
		
	
		
			
				
					|  |  |  |                 {{ | 
			
		
	
		
			
				
					|  |  |  |                   /* eslint-disable prettier/prettier */ | 
			
		
	
		
			
				
					|  |  |  |                   this.showGiveTotals | 
			
		
	
	
		
			
				
					|  |  | @ -203,15 +204,17 @@ | 
			
		
	
		
			
				
					|  |  |  |                         : (givenByMeUnconfirmed[contact.did] || 0) | 
			
		
	
		
			
				
					|  |  |  |                   /* eslint-enable prettier/prettier */ | 
			
		
	
		
			
				
					|  |  |  |                 }} | 
			
		
	
		
			
				
					|  |  |  |                 <br /> | 
			
		
	
		
			
				
					|  |  |  |                 <fa icon="plus" /> | 
			
		
	
		
			
				
					|  |  |  |               </button> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |               <button | 
			
		
	
		
			
				
					|  |  |  |                 class="text-sm bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white -ml-1.5 px-2 py-1.5 rounded-r-md border-l" | 
			
		
	
		
			
				
					|  |  |  |                 @click="onClickAddGive(contact.did, activeDid)" | 
			
		
	
		
			
				
					|  |  |  |                 @click="showGiftedDialog(contact.did, this.activeDid)" | 
			
		
	
		
			
				
					|  |  |  |                 :title="givenToMeDescriptions[contact.did] || ''" | 
			
		
	
		
			
				
					|  |  |  |               > | 
			
		
	
		
			
				
					|  |  |  |                 From: | 
			
		
	
		
			
				
					|  |  |  |                 <br /> | 
			
		
	
		
			
				
					|  |  |  |                 {{ | 
			
		
	
		
			
				
					|  |  |  |                   /* eslint-disable prettier/prettier */ | 
			
		
	
		
			
				
					|  |  |  |                   this.showGiveTotals | 
			
		
	
	
		
			
				
					|  |  | @ -222,6 +225,7 @@ | 
			
		
	
		
			
				
					|  |  |  |                         : (givenToMeUnconfirmed[contact.did] || 0) | 
			
		
	
		
			
				
					|  |  |  |                   /* eslint-enable prettier/prettier */ | 
			
		
	
		
			
				
					|  |  |  |                 }} | 
			
		
	
		
			
				
					|  |  |  |                 <br /> | 
			
		
	
		
			
				
					|  |  |  |                 <fa icon="plus" /> | 
			
		
	
		
			
				
					|  |  |  |               </button> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -237,7 +241,7 @@ | 
			
		
	
		
			
				
					|  |  |  |                   name: 'contact-amounts', | 
			
		
	
		
			
				
					|  |  |  |                   query: { contactDid: contact.did }, | 
			
		
	
		
			
				
					|  |  |  |                 }" | 
			
		
	
		
			
				
					|  |  |  |                 class="text-sm bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-1.5 rounded-md" | 
			
		
	
		
			
				
					|  |  |  |                 class="text-sm bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-1.5 rounded-md border border-slate-400" | 
			
		
	
		
			
				
					|  |  |  |                 title="See more given activity" | 
			
		
	
		
			
				
					|  |  |  |               > | 
			
		
	
		
			
				
					|  |  |  |                 <fa icon="file-lines" class="fa-fw" /> | 
			
		
	
	
		
			
				
					|  |  | @ -249,6 +253,7 @@ | 
			
		
	
		
			
				
					|  |  |  |     </ul> | 
			
		
	
		
			
				
					|  |  |  |     <p v-else>There are no contacts.</p> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     <GiftedDialog ref="customGivenDialog" /> | 
			
		
	
		
			
				
					|  |  |  |     <OfferDialog ref="customOfferDialog" /> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     <div v-if="showLargeIdenticon" class="fixed z-[100] top-0 inset-x-0 w-full"> | 
			
		
	
	
		
			
				
					|  |  | @ -313,8 +318,8 @@ import { | 
			
		
	
		
			
				
					|  |  |  | import { | 
			
		
	
		
			
				
					|  |  |  |   CONTACT_CSV_HEADER, | 
			
		
	
		
			
				
					|  |  |  |   CONTACT_URL_PREFIX, | 
			
		
	
		
			
				
					|  |  |  |   GiverReceiverInputInfo, | 
			
		
	
		
			
				
					|  |  |  |   GiveSummaryRecord, | 
			
		
	
		
			
				
					|  |  |  |   GiveVerifiableCredential, | 
			
		
	
		
			
				
					|  |  |  |   isDid, | 
			
		
	
		
			
				
					|  |  |  |   RegisterVerifiableCredential, | 
			
		
	
		
			
				
					|  |  |  |   SERVICE_ID, | 
			
		
	
	
		
			
				
					|  |  | @ -322,13 +327,14 @@ import { | 
			
		
	
		
			
				
					|  |  |  | import * as libsUtil from "@/libs/util"; | 
			
		
	
		
			
				
					|  |  |  | import QuickNav from "@/components/QuickNav.vue"; | 
			
		
	
		
			
				
					|  |  |  | import EntityIcon from "@/components/EntityIcon.vue"; | 
			
		
	
		
			
				
					|  |  |  | import GiftedDialog from "@/components/GiftedDialog.vue"; | 
			
		
	
		
			
				
					|  |  |  | import OfferDialog from "@/components/OfferDialog.vue"; | 
			
		
	
		
			
				
					|  |  |  | import { Account } from "@/db/tables/accounts"; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | import { Buffer } from "buffer/"; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | @Component({ | 
			
		
	
		
			
				
					|  |  |  |   components: { EntityIcon, OfferDialog, QuickNav }, | 
			
		
	
		
			
				
					|  |  |  |   components: { GiftedDialog, EntityIcon, OfferDialog, QuickNav }, | 
			
		
	
		
			
				
					|  |  |  | }) | 
			
		
	
		
			
				
					|  |  |  | export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |   $notify!: (notification: NotificationIface, timeout?: number) => void; | 
			
		
	
	
		
			
				
					|  |  | @ -352,8 +358,6 @@ export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |   givenToMeConfirmed: Record<string, number> = {}; | 
			
		
	
		
			
				
					|  |  |  |   // { "did:...": amount } entry for each contact | 
			
		
	
		
			
				
					|  |  |  |   givenToMeUnconfirmed: Record<string, number> = {}; | 
			
		
	
		
			
				
					|  |  |  |   hourDescriptionInput = ""; | 
			
		
	
		
			
				
					|  |  |  |   hourInput = "0"; | 
			
		
	
		
			
				
					|  |  |  |   isRegistered = false; | 
			
		
	
		
			
				
					|  |  |  |   showDidCopy = false; | 
			
		
	
		
			
				
					|  |  |  |   showGiveNumbers = false; | 
			
		
	
	
		
			
				
					|  |  | @ -1041,27 +1045,33 @@ export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   private nameForDid(contacts: Array<Contact>, did: string): string { | 
			
		
	
		
			
				
					|  |  |  |     if (did === this.activeDid) { | 
			
		
	
		
			
				
					|  |  |  |       return "you"; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     const contact = R.find((con) => con.did == did, contacts); | 
			
		
	
		
			
				
					|  |  |  |     return this.nameForContact(contact); | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   private nameForContact(contact?: Contact, capitalize?: boolean): string { | 
			
		
	
		
			
				
					|  |  |  |     return contact?.name || (capitalize ? "T" : "t") + "his unnamed user"; | 
			
		
	
		
			
				
					|  |  |  |     return ( | 
			
		
	
		
			
				
					|  |  |  |       (contact?.name as string) || (capitalize ? "T" : "t") + "his unnamed user" | 
			
		
	
		
			
				
					|  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   async onClickAddGive(fromDid: string, toDid: string): Promise<void> { | 
			
		
	
		
			
				
					|  |  |  |     const identity = await this.getIdentity(this.activeDid); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   private showGiftedDialog(giverDid: string, recipientDid: string) { | 
			
		
	
		
			
				
					|  |  |  |     // if they have unconfirmed amounts, ask to confirm those first | 
			
		
	
		
			
				
					|  |  |  |     if (toDid == identity?.did && this.givenToMeUnconfirmed[fromDid] > 0) { | 
			
		
	
		
			
				
					|  |  |  |       const isare = this.givenToMeUnconfirmed[fromDid] == 1 ? "is" : "are"; | 
			
		
	
		
			
				
					|  |  |  |       const hours = this.givenToMeUnconfirmed[fromDid] == 1 ? "hour" : "hours"; | 
			
		
	
		
			
				
					|  |  |  |     if ( | 
			
		
	
		
			
				
					|  |  |  |       recipientDid == this.activeDid && | 
			
		
	
		
			
				
					|  |  |  |       this.givenToMeUnconfirmed[giverDid] > 0 | 
			
		
	
		
			
				
					|  |  |  |     ) { | 
			
		
	
		
			
				
					|  |  |  |       const isAre = this.givenToMeUnconfirmed[giverDid] == 1 ? "is" : "are"; | 
			
		
	
		
			
				
					|  |  |  |       const hours = this.givenToMeUnconfirmed[giverDid] == 1 ? "hour" : "hours"; | 
			
		
	
		
			
				
					|  |  |  |       if ( | 
			
		
	
		
			
				
					|  |  |  |         confirm( | 
			
		
	
		
			
				
					|  |  |  |           "There " + | 
			
		
	
		
			
				
					|  |  |  |             isare + | 
			
		
	
		
			
				
					|  |  |  |             isAre + | 
			
		
	
		
			
				
					|  |  |  |             " " + | 
			
		
	
		
			
				
					|  |  |  |             this.givenToMeUnconfirmed[fromDid] + | 
			
		
	
		
			
				
					|  |  |  |             this.givenToMeUnconfirmed[giverDid] + | 
			
		
	
		
			
				
					|  |  |  |             " unconfirmed " + | 
			
		
	
		
			
				
					|  |  |  |             hours + | 
			
		
	
		
			
				
					|  |  |  |             " from them." + | 
			
		
	
	
		
			
				
					|  |  | @ -1070,178 +1080,58 @@ export default class ContactsView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |       ) { | 
			
		
	
		
			
				
					|  |  |  |         this.$router.push({ | 
			
		
	
		
			
				
					|  |  |  |           name: "contact-amounts", | 
			
		
	
		
			
				
					|  |  |  |           query: { contactDid: fromDid }, | 
			
		
	
		
			
				
					|  |  |  |           query: { contactDid: giverDid }, | 
			
		
	
		
			
				
					|  |  |  |         }); | 
			
		
	
		
			
				
					|  |  |  |         return; | 
			
		
	
		
			
				
					|  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     if (!libsUtil.isNumeric(this.hourInput)) { | 
			
		
	
		
			
				
					|  |  |  |       this.$notify( | 
			
		
	
		
			
				
					|  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |           group: "alert", | 
			
		
	
		
			
				
					|  |  |  |           type: "danger", | 
			
		
	
		
			
				
					|  |  |  |           title: "Input Error", | 
			
		
	
		
			
				
					|  |  |  |           text: "This is not a valid number of hours: " + this.hourInput, | 
			
		
	
		
			
				
					|  |  |  |         }, | 
			
		
	
		
			
				
					|  |  |  |         3000, | 
			
		
	
		
			
				
					|  |  |  |       ); | 
			
		
	
		
			
				
					|  |  |  |     } else if (parseFloat(this.hourInput) == 0 && !this.hourDescriptionInput) { | 
			
		
	
		
			
				
					|  |  |  |       this.$notify( | 
			
		
	
		
			
				
					|  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |           group: "alert", | 
			
		
	
		
			
				
					|  |  |  |           type: "danger", | 
			
		
	
		
			
				
					|  |  |  |           title: "Input Error", | 
			
		
	
		
			
				
					|  |  |  |           text: "Giving no hours or description does nothing.", | 
			
		
	
		
			
				
					|  |  |  |         }, | 
			
		
	
		
			
				
					|  |  |  |         3000, | 
			
		
	
		
			
				
					|  |  |  |       ); | 
			
		
	
		
			
				
					|  |  |  |     } else if (!identity) { | 
			
		
	
		
			
				
					|  |  |  |       this.$notify( | 
			
		
	
		
			
				
					|  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |           group: "alert", | 
			
		
	
		
			
				
					|  |  |  |           type: "danger", | 
			
		
	
		
			
				
					|  |  |  |           title: "Status Error", | 
			
		
	
		
			
				
					|  |  |  |           text: "No identifier is available.", | 
			
		
	
		
			
				
					|  |  |  |         }, | 
			
		
	
		
			
				
					|  |  |  |         3000, | 
			
		
	
		
			
				
					|  |  |  |       ); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     let giver: GiverReceiverInputInfo, receiver: GiverReceiverInputInfo; | 
			
		
	
		
			
				
					|  |  |  |     if (giverDid) { | 
			
		
	
		
			
				
					|  |  |  |       giver = { | 
			
		
	
		
			
				
					|  |  |  |         did: giverDid, | 
			
		
	
		
			
				
					|  |  |  |         name: this.nameForDid(this.contacts, giverDid), | 
			
		
	
		
			
				
					|  |  |  |       }; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     if (recipientDid) { | 
			
		
	
		
			
				
					|  |  |  |       receiver = { | 
			
		
	
		
			
				
					|  |  |  |         did: recipientDid, | 
			
		
	
		
			
				
					|  |  |  |         name: this.nameForDid(this.contacts, recipientDid), | 
			
		
	
		
			
				
					|  |  |  |       }; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     let callback: (amount: number) => void; | 
			
		
	
		
			
				
					|  |  |  |     let customTitle = "Given"; | 
			
		
	
		
			
				
					|  |  |  |     // choose whether to open dialog to user or from user | 
			
		
	
		
			
				
					|  |  |  |     if (giverDid == this.activeDid) { | 
			
		
	
		
			
				
					|  |  |  |       callback = (amount: number) => { | 
			
		
	
		
			
				
					|  |  |  |         const newList = R.clone(this.givenByMeUnconfirmed); | 
			
		
	
		
			
				
					|  |  |  |         newList[recipientDid] = (newList[recipientDid] || 0) + amount; | 
			
		
	
		
			
				
					|  |  |  |         this.givenByMeUnconfirmed = newList; | 
			
		
	
		
			
				
					|  |  |  |       }; | 
			
		
	
		
			
				
					|  |  |  |       customTitle = "To " + receiver.name; | 
			
		
	
		
			
				
					|  |  |  |     } else { | 
			
		
	
		
			
				
					|  |  |  |       // ask to confirm amount | 
			
		
	
		
			
				
					|  |  |  |       let toFrom; | 
			
		
	
		
			
				
					|  |  |  |       if (fromDid == identity?.did) { | 
			
		
	
		
			
				
					|  |  |  |         toFrom = "from you to " + this.nameForDid(this.contacts, toDid); | 
			
		
	
		
			
				
					|  |  |  |       } else { | 
			
		
	
		
			
				
					|  |  |  |         toFrom = "from " + this.nameForDid(this.contacts, fromDid) + " to you"; | 
			
		
	
		
			
				
					|  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |       let description; | 
			
		
	
		
			
				
					|  |  |  |       if (this.hourDescriptionInput) { | 
			
		
	
		
			
				
					|  |  |  |         description = " with description '" + this.hourDescriptionInput + "'"; | 
			
		
	
		
			
				
					|  |  |  |       } else { | 
			
		
	
		
			
				
					|  |  |  |         description = " with no description"; | 
			
		
	
		
			
				
					|  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |       if ( | 
			
		
	
		
			
				
					|  |  |  |         confirm( | 
			
		
	
		
			
				
					|  |  |  |           "Are you sure you want to record " + | 
			
		
	
		
			
				
					|  |  |  |             this.hourInput + | 
			
		
	
		
			
				
					|  |  |  |             " hour" + | 
			
		
	
		
			
				
					|  |  |  |             (this.hourInput == "1" ? "" : "s") + | 
			
		
	
		
			
				
					|  |  |  |             " " + | 
			
		
	
		
			
				
					|  |  |  |             toFrom + | 
			
		
	
		
			
				
					|  |  |  |             description + | 
			
		
	
		
			
				
					|  |  |  |             "?", | 
			
		
	
		
			
				
					|  |  |  |         ) | 
			
		
	
		
			
				
					|  |  |  |       ) { | 
			
		
	
		
			
				
					|  |  |  |         this.createAndSubmitContactGive( | 
			
		
	
		
			
				
					|  |  |  |           identity, | 
			
		
	
		
			
				
					|  |  |  |           fromDid, | 
			
		
	
		
			
				
					|  |  |  |           toDid, | 
			
		
	
		
			
				
					|  |  |  |           parseFloat(this.hourInput), | 
			
		
	
		
			
				
					|  |  |  |           this.hourDescriptionInput, | 
			
		
	
		
			
				
					|  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |       // must be (recipientDid == this.activeDid) | 
			
		
	
		
			
				
					|  |  |  |       callback = (amount: number) => { | 
			
		
	
		
			
				
					|  |  |  |         const newList = R.clone(this.givenToMeUnconfirmed); | 
			
		
	
		
			
				
					|  |  |  |         newList[giverDid] = (newList[giverDid] || 0) + amount; | 
			
		
	
		
			
				
					|  |  |  |         this.givenToMeUnconfirmed = newList; | 
			
		
	
		
			
				
					|  |  |  |       }; | 
			
		
	
		
			
				
					|  |  |  |       customTitle = "From " + giver.name; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     (this.$refs.customGivenDialog as GiftedDialog).open( | 
			
		
	
		
			
				
					|  |  |  |       giver, | 
			
		
	
		
			
				
					|  |  |  |       receiver, | 
			
		
	
		
			
				
					|  |  |  |       undefined as string, | 
			
		
	
		
			
				
					|  |  |  |       customTitle, | 
			
		
	
		
			
				
					|  |  |  |       callback, | 
			
		
	
		
			
				
					|  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   openOfferDialog(recipientDid: string) { | 
			
		
	
		
			
				
					|  |  |  |     (this.$refs.customOfferDialog as OfferDialog).open(recipientDid); | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   // similar function is in endorserServer.ts | 
			
		
	
		
			
				
					|  |  |  |   private async createAndSubmitContactGive( | 
			
		
	
		
			
				
					|  |  |  |     identity: IIdentifier, | 
			
		
	
		
			
				
					|  |  |  |     fromDid: string, | 
			
		
	
		
			
				
					|  |  |  |     toDid: string, | 
			
		
	
		
			
				
					|  |  |  |     amount: number, | 
			
		
	
		
			
				
					|  |  |  |     description: string, | 
			
		
	
		
			
				
					|  |  |  |   ): Promise<void> { | 
			
		
	
		
			
				
					|  |  |  |     // Make a claim | 
			
		
	
		
			
				
					|  |  |  |     const vcClaim: GiveVerifiableCredential = { | 
			
		
	
		
			
				
					|  |  |  |       "@context": "https://schema.org", | 
			
		
	
		
			
				
					|  |  |  |       "@type": "GiveAction", | 
			
		
	
		
			
				
					|  |  |  |       agent: { identifier: fromDid }, | 
			
		
	
		
			
				
					|  |  |  |       object: { amountOfThisGood: amount, unitCode: "HUR" }, | 
			
		
	
		
			
				
					|  |  |  |       recipient: { identifier: toDid }, | 
			
		
	
		
			
				
					|  |  |  |     }; | 
			
		
	
		
			
				
					|  |  |  |     if (description) { | 
			
		
	
		
			
				
					|  |  |  |       vcClaim.description = description; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     // Make a payload for the claim | 
			
		
	
		
			
				
					|  |  |  |     const vcPayload = { | 
			
		
	
		
			
				
					|  |  |  |       vc: { | 
			
		
	
		
			
				
					|  |  |  |         "@context": ["https://www.w3.org/2018/credentials/v1"], | 
			
		
	
		
			
				
					|  |  |  |         type: ["VerifiableCredential"], | 
			
		
	
		
			
				
					|  |  |  |         credentialSubject: vcClaim, | 
			
		
	
		
			
				
					|  |  |  |       }, | 
			
		
	
		
			
				
					|  |  |  |     }; | 
			
		
	
		
			
				
					|  |  |  |     // Create a signature using private key of identity | 
			
		
	
		
			
				
					|  |  |  |     if (identity.keys[0].privateKeyHex !== null) { | 
			
		
	
		
			
				
					|  |  |  |       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | 
			
		
	
		
			
				
					|  |  |  |       const privateKeyHex: string = identity.keys[0].privateKeyHex!; | 
			
		
	
		
			
				
					|  |  |  |       const signer = await SimpleSigner(privateKeyHex); | 
			
		
	
		
			
				
					|  |  |  |       const alg = undefined; | 
			
		
	
		
			
				
					|  |  |  |       // Create a JWT for the request | 
			
		
	
		
			
				
					|  |  |  |       const vcJwt: string = await didJwt.createJWT(vcPayload, { | 
			
		
	
		
			
				
					|  |  |  |         alg: alg, | 
			
		
	
		
			
				
					|  |  |  |         issuer: identity.did, | 
			
		
	
		
			
				
					|  |  |  |         signer: signer, | 
			
		
	
		
			
				
					|  |  |  |       }); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |       // Make the xhr request payload | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |       const payload = JSON.stringify({ jwtEncoded: vcJwt }); | 
			
		
	
		
			
				
					|  |  |  |       const url = this.apiServer + "/api/v2/claim"; | 
			
		
	
		
			
				
					|  |  |  |       const headers = await this.getHeaders(identity); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |       try { | 
			
		
	
		
			
				
					|  |  |  |         const resp = await this.axios.post(url, payload, { headers }); | 
			
		
	
		
			
				
					|  |  |  |         if (resp.data?.success?.handleId) { | 
			
		
	
		
			
				
					|  |  |  |           this.$notify( | 
			
		
	
		
			
				
					|  |  |  |             { | 
			
		
	
		
			
				
					|  |  |  |               group: "alert", | 
			
		
	
		
			
				
					|  |  |  |               type: "success", | 
			
		
	
		
			
				
					|  |  |  |               title: "Done", | 
			
		
	
		
			
				
					|  |  |  |               text: "Successfully logged time to the server.", | 
			
		
	
		
			
				
					|  |  |  |             }, | 
			
		
	
		
			
				
					|  |  |  |             5000, | 
			
		
	
		
			
				
					|  |  |  |           ); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |           if (fromDid === identity.did) { | 
			
		
	
		
			
				
					|  |  |  |             const newList = R.clone(this.givenByMeUnconfirmed); | 
			
		
	
		
			
				
					|  |  |  |             newList[toDid] = (newList[toDid] || 0) + amount; | 
			
		
	
		
			
				
					|  |  |  |             this.givenByMeUnconfirmed = newList; | 
			
		
	
		
			
				
					|  |  |  |           } else { | 
			
		
	
		
			
				
					|  |  |  |             const newList = R.clone(this.givenToMeConfirmed); | 
			
		
	
		
			
				
					|  |  |  |             newList[fromDid] = (newList[fromDid] || 0) + amount; | 
			
		
	
		
			
				
					|  |  |  |             this.givenToMeConfirmed = newList; | 
			
		
	
		
			
				
					|  |  |  |           } | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |       } catch (error) { | 
			
		
	
		
			
				
					|  |  |  |         console.error("Error in createAndSubmitContactGive: ", error); | 
			
		
	
		
			
				
					|  |  |  |         let userMessage = "There was an error. See logs for more info."; | 
			
		
	
		
			
				
					|  |  |  |         const serverError = error as AxiosError; | 
			
		
	
		
			
				
					|  |  |  |         if (serverError) { | 
			
		
	
		
			
				
					|  |  |  |           if (serverError.message) { | 
			
		
	
		
			
				
					|  |  |  |             userMessage = serverError.message; // Info for the user | 
			
		
	
		
			
				
					|  |  |  |           } else { | 
			
		
	
		
			
				
					|  |  |  |             userMessage = JSON.stringify(serverError.toJSON()); | 
			
		
	
		
			
				
					|  |  |  |           } | 
			
		
	
		
			
				
					|  |  |  |         } else { | 
			
		
	
		
			
				
					|  |  |  |           userMessage = error as string; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         // Now set that error for the user to see. | 
			
		
	
		
			
				
					|  |  |  |         this.$notify( | 
			
		
	
		
			
				
					|  |  |  |           { | 
			
		
	
		
			
				
					|  |  |  |             group: "alert", | 
			
		
	
		
			
				
					|  |  |  |             type: "danger", | 
			
		
	
		
			
				
					|  |  |  |             title: "Error Sending Give", | 
			
		
	
		
			
				
					|  |  |  |             text: userMessage, | 
			
		
	
		
			
				
					|  |  |  |           }, | 
			
		
	
		
			
				
					|  |  |  |           5000, | 
			
		
	
		
			
				
					|  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   private async onClickCancelName() { | 
			
		
	
		
			
				
					|  |  |  |     this.contactEdit = null; | 
			
		
	
		
			
				
					|  |  |  |     this.contactNewName = ""; | 
			
		
	
	
		
			
				
					|  |  | 
 |