|  |  | @ -1,5 +1,5 @@ | 
			
		
	
		
			
				
					|  |  |  | <template> | 
			
		
	
		
			
				
					|  |  |  |   <QuickNav selected="Home"></QuickNav> | 
			
		
	
		
			
				
					|  |  |  |   <QuickNav selected="Home" /> | 
			
		
	
		
			
				
					|  |  |  |   <TopMessage /> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   <!-- CONTENT --> | 
			
		
	
	
		
			
				
					|  |  | @ -30,7 +30,7 @@ | 
			
		
	
		
			
				
					|  |  |  |             and go click on that new app. | 
			
		
	
		
			
				
					|  |  |  |           </span> | 
			
		
	
		
			
				
					|  |  |  |           <span | 
			
		
	
		
			
				
					|  |  |  |             v-else-if="userAgentInfo.getBrowser().name.startsWith('Chrome')" | 
			
		
	
		
			
				
					|  |  |  |             v-else-if="userAgentInfo.getBrowser()?.name?.startsWith('Chrome')" | 
			
		
	
		
			
				
					|  |  |  |           > | 
			
		
	
		
			
				
					|  |  |  |             You should see a prompt to install, or you can click on the | 
			
		
	
		
			
				
					|  |  |  |             top-right dots | 
			
		
	
	
		
			
				
					|  |  | @ -105,14 +105,8 @@ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |       <div v-else> | 
			
		
	
		
			
				
					|  |  |  |         <!-- activeDid && isRegistered --> | 
			
		
	
		
			
				
					|  |  |  |         <div class="flex justify-between mb-4"> | 
			
		
	
		
			
				
					|  |  |  |           <h2 class="text-xl font-bold">Record Something Given</h2> | 
			
		
	
		
			
				
					|  |  |  |           <button | 
			
		
	
		
			
				
					|  |  |  |             @click="openGiftedPrompts()" | 
			
		
	
		
			
				
					|  |  |  |             class="block text-center text-md font-bold bg-blue-500 text-white px-2 py-3 rounded-md" | 
			
		
	
		
			
				
					|  |  |  |           > | 
			
		
	
		
			
				
					|  |  |  |             Ideas... | 
			
		
	
		
			
				
					|  |  |  |           </button> | 
			
		
	
		
			
				
					|  |  |  |         <div class="mb-4"> | 
			
		
	
		
			
				
					|  |  |  |           <h2 class="text-xl font-bold">Record Something Given By:</h2> | 
			
		
	
		
			
				
					|  |  |  |         </div> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         <ul class="grid grid-cols-4 gap-x-3 gap-y-5 text-center mb-5"> | 
			
		
	
	
		
			
				
					|  |  | @ -145,21 +139,20 @@ | 
			
		
	
		
			
				
					|  |  |  |           </li> | 
			
		
	
		
			
				
					|  |  |  |         </ul> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         <!-- Ideally, this button should only be visible when the active account has more than 7 or 11 contacts in their list (we want to limit the grid count above to 8 or 12 accounts to keep it compact) --> | 
			
		
	
		
			
				
					|  |  |  |         <router-link | 
			
		
	
		
			
				
					|  |  |  |           v-if="allContacts.length >= 7" | 
			
		
	
		
			
				
					|  |  |  |           :to="{ name: 'contact-gives' }" | 
			
		
	
		
			
				
					|  |  |  |           class="block text-center text-md font-bold uppercase bg-slate-500 text-white px-2 py-3 rounded-md" | 
			
		
	
		
			
				
					|  |  |  |         > | 
			
		
	
		
			
				
					|  |  |  |           Show More Contacts… | 
			
		
	
		
			
				
					|  |  |  |         </router-link> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         <!-- If there are no contacts, show this instead: --> | 
			
		
	
		
			
				
					|  |  |  |         <div | 
			
		
	
		
			
				
					|  |  |  |           class="rounded border border-dashed border-slate-300 bg-slate-100 px-4 py-3 text-center italic text-slate-500" | 
			
		
	
		
			
				
					|  |  |  |           v-if="allContacts.length === 0" | 
			
		
	
		
			
				
					|  |  |  |         > | 
			
		
	
		
			
				
					|  |  |  |           (No contacts to show.) | 
			
		
	
		
			
				
					|  |  |  |         <div class="flex justify-between"> | 
			
		
	
		
			
				
					|  |  |  |           <router-link | 
			
		
	
		
			
				
					|  |  |  |             v-if="allContacts.length >= 7" | 
			
		
	
		
			
				
					|  |  |  |             :to="{ name: 'contact-gives' }" | 
			
		
	
		
			
				
					|  |  |  |             class="block text-center text-md font-bold uppercase bg-slate-500 text-white px-2 py-3 rounded-md" | 
			
		
	
		
			
				
					|  |  |  |           > | 
			
		
	
		
			
				
					|  |  |  |             Choose From All Contacts | 
			
		
	
		
			
				
					|  |  |  |           </router-link> | 
			
		
	
		
			
				
					|  |  |  |           <button | 
			
		
	
		
			
				
					|  |  |  |             @click="openGiftedPrompts()" | 
			
		
	
		
			
				
					|  |  |  |             class="block text-center text-md font-bold bg-slate-500 text-white px-2 py-3 rounded-md" | 
			
		
	
		
			
				
					|  |  |  |           > | 
			
		
	
		
			
				
					|  |  |  |             Ideas... | 
			
		
	
		
			
				
					|  |  |  |           </button> | 
			
		
	
		
			
				
					|  |  |  |         </div> | 
			
		
	
		
			
				
					|  |  |  |       </div> | 
			
		
	
		
			
				
					|  |  |  |     </div> | 
			
		
	
	
		
			
				
					|  |  | @ -185,16 +178,24 @@ | 
			
		
	
		
			
				
					|  |  |  |               class="border-b border-dashed border-slate-400 text-orange-400 pb-2 mb-2 font-bold uppercase text-sm" | 
			
		
	
		
			
				
					|  |  |  |               v-if="record.jwtId == feedLastViewedClaimId" | 
			
		
	
		
			
				
					|  |  |  |             > | 
			
		
	
		
			
				
					|  |  |  |               You've seen all the following before | 
			
		
	
		
			
				
					|  |  |  |               You've already seen all the following | 
			
		
	
		
			
				
					|  |  |  |             </div> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             <div class="grid grid-cols-12"> | 
			
		
	
		
			
				
					|  |  |  |               <span class="col-span-11 justify-self-start"> | 
			
		
	
		
			
				
					|  |  |  |                 <fa | 
			
		
	
		
			
				
					|  |  |  |                   icon="gift" | 
			
		
	
		
			
				
					|  |  |  |                   class="col-span-1 pt-1 pr-2 text-slate-500" | 
			
		
	
		
			
				
					|  |  |  |                 ></fa> | 
			
		
	
		
			
				
					|  |  |  |                 {{ this.giveDescription(record) }} | 
			
		
	
		
			
				
					|  |  |  |                 <span> | 
			
		
	
		
			
				
					|  |  |  |                   <fa | 
			
		
	
		
			
				
					|  |  |  |                     v-if="record.giver.known || record.receiver.known" | 
			
		
	
		
			
				
					|  |  |  |                     icon="circle-user" | 
			
		
	
		
			
				
					|  |  |  |                     class="col-span-1 pt-1 pl-0 pr-3 text-slate-500" | 
			
		
	
		
			
				
					|  |  |  |                   /> | 
			
		
	
		
			
				
					|  |  |  |                   <fa | 
			
		
	
		
			
				
					|  |  |  |                     v-else | 
			
		
	
		
			
				
					|  |  |  |                     icon="gift" | 
			
		
	
		
			
				
					|  |  |  |                     class="col-span-1 pt-1 pl-3 pr-0 text-slate-500" | 
			
		
	
		
			
				
					|  |  |  |                   /> | 
			
		
	
		
			
				
					|  |  |  |                 </span> | 
			
		
	
		
			
				
					|  |  |  |                 {{ giveDescription(record) }} | 
			
		
	
		
			
				
					|  |  |  |                 <a @click="onClickLoadClaim(record.jwtId)"> | 
			
		
	
		
			
				
					|  |  |  |                   <fa | 
			
		
	
		
			
				
					|  |  |  |                     icon="circle-info" | 
			
		
	
	
		
			
				
					|  |  | @ -243,7 +244,8 @@ import { Contact } from "@/db/tables/contacts"; | 
			
		
	
		
			
				
					|  |  |  | import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings"; | 
			
		
	
		
			
				
					|  |  |  | import { accessToken } from "@/libs/crypto"; | 
			
		
	
		
			
				
					|  |  |  | import { | 
			
		
	
		
			
				
					|  |  |  |   didInfo, | 
			
		
	
		
			
				
					|  |  |  |   contactForDid, | 
			
		
	
		
			
				
					|  |  |  |   didInfoForContact, | 
			
		
	
		
			
				
					|  |  |  |   GiverInputInfo, | 
			
		
	
		
			
				
					|  |  |  |   GiveServerRecord, | 
			
		
	
		
			
				
					|  |  |  | } from "@/libs/endorserServer"; | 
			
		
	
	
		
			
				
					|  |  | @ -257,6 +259,17 @@ interface Notification { | 
			
		
	
		
			
				
					|  |  |  |   text: string; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | interface GiveRecordWithContactInfo extends GiveServerRecord { | 
			
		
	
		
			
				
					|  |  |  |   giver: { | 
			
		
	
		
			
				
					|  |  |  |     displayName: string; | 
			
		
	
		
			
				
					|  |  |  |     known: boolean; | 
			
		
	
		
			
				
					|  |  |  |   }; | 
			
		
	
		
			
				
					|  |  |  |   receiver: { | 
			
		
	
		
			
				
					|  |  |  |     displayName: string; | 
			
		
	
		
			
				
					|  |  |  |     known: boolean; | 
			
		
	
		
			
				
					|  |  |  |   }; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | @Component({ | 
			
		
	
		
			
				
					|  |  |  |   components: { | 
			
		
	
		
			
				
					|  |  |  |     GiftedDialog, | 
			
		
	
	
		
			
				
					|  |  | @ -274,7 +287,7 @@ export default class HomeView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |   allContacts: Array<Contact> = []; | 
			
		
	
		
			
				
					|  |  |  |   allMyDids: Array<string> = []; | 
			
		
	
		
			
				
					|  |  |  |   apiServer = ""; | 
			
		
	
		
			
				
					|  |  |  |   feedData: GiveServerRecord[] = []; | 
			
		
	
		
			
				
					|  |  |  |   feedData: GiveRecordWithContactInfo[] = []; | 
			
		
	
		
			
				
					|  |  |  |   feedPreviousOldestId?: string; | 
			
		
	
		
			
				
					|  |  |  |   feedLastViewedClaimId?: string; | 
			
		
	
		
			
				
					|  |  |  |   isCreatingIdentifier = false; | 
			
		
	
	
		
			
				
					|  |  | @ -388,7 +401,37 @@ export default class HomeView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |     await this.retrieveGives(this.apiServer, this.feedPreviousOldestId) | 
			
		
	
		
			
				
					|  |  |  |       .then(async (results) => { | 
			
		
	
		
			
				
					|  |  |  |         if (results.data.length > 0) { | 
			
		
	
		
			
				
					|  |  |  |           this.feedData = this.feedData.concat(results.data); | 
			
		
	
		
			
				
					|  |  |  |           // include the descriptions of the giver and receiver | 
			
		
	
		
			
				
					|  |  |  |           const newFeedData: GiveRecordWithContactInfo = results.data.map( | 
			
		
	
		
			
				
					|  |  |  |             (record: GiveServerRecord) => { | 
			
		
	
		
			
				
					|  |  |  |               // similar code is in endorser-mobile utility.ts | 
			
		
	
		
			
				
					|  |  |  |               // claim.claim happen for some claims wrapped in a Verifiable Credential | 
			
		
	
		
			
				
					|  |  |  |               // eslint-disable-next-line @typescript-eslint/no-explicit-any | 
			
		
	
		
			
				
					|  |  |  |               const claim = (record.fullClaim as any).claim || record.fullClaim; | 
			
		
	
		
			
				
					|  |  |  |               // agent.did is for legacy data, before March 2023 | 
			
		
	
		
			
				
					|  |  |  |               const giverDid = | 
			
		
	
		
			
				
					|  |  |  |                 claim.agent?.identifier || (claim.agent as any)?.did; // eslint-disable-line @typescript-eslint/no-explicit-any | 
			
		
	
		
			
				
					|  |  |  |               // recipient.did is for legacy data, before March 2023 | 
			
		
	
		
			
				
					|  |  |  |               const recipientDid = | 
			
		
	
		
			
				
					|  |  |  |                 claim.recipient?.identifier || (claim.recipient as any)?.did; // eslint-disable-line @typescript-eslint/no-explicit-any | 
			
		
	
		
			
				
					|  |  |  |               return { | 
			
		
	
		
			
				
					|  |  |  |                 ...record, | 
			
		
	
		
			
				
					|  |  |  |                 giver: didInfoForContact( | 
			
		
	
		
			
				
					|  |  |  |                   giverDid, | 
			
		
	
		
			
				
					|  |  |  |                   this.activeDid, | 
			
		
	
		
			
				
					|  |  |  |                   contactForDid(giverDid, this.allContacts), | 
			
		
	
		
			
				
					|  |  |  |                   this.allMyDids, | 
			
		
	
		
			
				
					|  |  |  |                 ), | 
			
		
	
		
			
				
					|  |  |  |                 receiver: didInfoForContact( | 
			
		
	
		
			
				
					|  |  |  |                   recipientDid, | 
			
		
	
		
			
				
					|  |  |  |                   this.activeDid, | 
			
		
	
		
			
				
					|  |  |  |                   contactForDid(recipientDid, this.allContacts), | 
			
		
	
		
			
				
					|  |  |  |                   this.allMyDids, | 
			
		
	
		
			
				
					|  |  |  |                 ), | 
			
		
	
		
			
				
					|  |  |  |               }; | 
			
		
	
		
			
				
					|  |  |  |             }, | 
			
		
	
		
			
				
					|  |  |  |           ); | 
			
		
	
		
			
				
					|  |  |  |           this.feedData = this.feedData.concat(newFeedData); | 
			
		
	
		
			
				
					|  |  |  |           this.feedPreviousOldestId = | 
			
		
	
		
			
				
					|  |  |  |             results.data[results.data.length - 1].jwtId; | 
			
		
	
		
			
				
					|  |  |  |           // The following update is only done on the first load. | 
			
		
	
	
		
			
				
					|  |  | @ -449,46 +492,52 @@ export default class HomeView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   giveDescription(giveRecord: GiveServerRecord) { | 
			
		
	
		
			
				
					|  |  |  |   giveDescription(giveRecord: GiveRecordWithContactInfo) { | 
			
		
	
		
			
				
					|  |  |  |     // similar code is in endorser-mobile utility.ts | 
			
		
	
		
			
				
					|  |  |  |     // claim.claim happen for some claims wrapped in a Verifiable Credential | 
			
		
	
		
			
				
					|  |  |  |     // eslint-disable-next-line @typescript-eslint/no-explicit-any | 
			
		
	
		
			
				
					|  |  |  |     const claim = (giveRecord.fullClaim as any).claim || giveRecord.fullClaim; | 
			
		
	
		
			
				
					|  |  |  |     // agent.did is for legacy data, before March 2023 | 
			
		
	
		
			
				
					|  |  |  |     // eslint-disable-next-line @typescript-eslint/no-explicit-any | 
			
		
	
		
			
				
					|  |  |  |     const giverDid = claim.agent?.identifier || (claim.agent as any)?.did; | 
			
		
	
		
			
				
					|  |  |  |     const giverInfo = didInfo( | 
			
		
	
		
			
				
					|  |  |  |       giverDid, | 
			
		
	
		
			
				
					|  |  |  |       this.activeDid, | 
			
		
	
		
			
				
					|  |  |  |       this.allMyDids, | 
			
		
	
		
			
				
					|  |  |  |       this.allContacts, | 
			
		
	
		
			
				
					|  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     let gaveAmount = claim.object?.amountOfThisGood | 
			
		
	
		
			
				
					|  |  |  |       ? this.displayAmount(claim.object.unitCode, claim.object.amountOfThisGood) | 
			
		
	
		
			
				
					|  |  |  |       : ""; | 
			
		
	
		
			
				
					|  |  |  |     if (claim.description) { | 
			
		
	
		
			
				
					|  |  |  |       if (gaveAmount) { | 
			
		
	
		
			
				
					|  |  |  |         gaveAmount = gaveAmount + ", and also: "; | 
			
		
	
		
			
				
					|  |  |  |         gaveAmount = " (and " + gaveAmount + ")"; | 
			
		
	
		
			
				
					|  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |       gaveAmount = gaveAmount + claim.description; | 
			
		
	
		
			
				
					|  |  |  |       gaveAmount = claim.description + gaveAmount; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     if (!gaveAmount) { | 
			
		
	
		
			
				
					|  |  |  |       gaveAmount = "something not described"; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     // recipient.did is for legacy data, before March 2023 | 
			
		
	
		
			
				
					|  |  |  |     const gaveRecipientId = | 
			
		
	
		
			
				
					|  |  |  |       // eslint-disable-next-line @typescript-eslint/no-explicit-any | 
			
		
	
		
			
				
					|  |  |  |       claim.recipient?.identifier || (claim.recipient as any)?.did; | 
			
		
	
		
			
				
					|  |  |  |     const gaveRecipientInfo = gaveRecipientId | 
			
		
	
		
			
				
					|  |  |  |       ? " to " + | 
			
		
	
		
			
				
					|  |  |  |         didInfo( | 
			
		
	
		
			
				
					|  |  |  |           gaveRecipientId, | 
			
		
	
		
			
				
					|  |  |  |           this.activeDid, | 
			
		
	
		
			
				
					|  |  |  |           this.allMyDids, | 
			
		
	
		
			
				
					|  |  |  |           this.allContacts, | 
			
		
	
		
			
				
					|  |  |  |         ) | 
			
		
	
		
			
				
					|  |  |  |       : ""; | 
			
		
	
		
			
				
					|  |  |  |     return giverInfo + " gave" + gaveRecipientInfo + ": " + gaveAmount; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     /** | 
			
		
	
		
			
				
					|  |  |  |      * Only show giver and/or receiver info first if they're named. | 
			
		
	
		
			
				
					|  |  |  |      * - If only giver is named, show "... gave" | 
			
		
	
		
			
				
					|  |  |  |      * - If only receiver is named, show "... received" | 
			
		
	
		
			
				
					|  |  |  |      */ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     const giverInfo = giveRecord.giver; | 
			
		
	
		
			
				
					|  |  |  |     const recipientInfo = giveRecord.receiver; | 
			
		
	
		
			
				
					|  |  |  |     if (giverInfo.known && recipientInfo.known) { | 
			
		
	
		
			
				
					|  |  |  |       // both giver and recipient are named | 
			
		
	
		
			
				
					|  |  |  |       return `${giverInfo.displayName} gave to ${recipientInfo.displayName}: ${gaveAmount}`; | 
			
		
	
		
			
				
					|  |  |  |     } else if (giverInfo.known) { | 
			
		
	
		
			
				
					|  |  |  |       // giver is named but recipient is not | 
			
		
	
		
			
				
					|  |  |  |       return `${giverInfo.displayName} gave: ${gaveAmount} (to ${recipientInfo.displayName})`; | 
			
		
	
		
			
				
					|  |  |  |     } else if (recipientInfo.known) { | 
			
		
	
		
			
				
					|  |  |  |       // recipient is named but giver is not | 
			
		
	
		
			
				
					|  |  |  |       return `${recipientInfo.displayName} received: ${gaveAmount} (from ${giverInfo.displayName})`; | 
			
		
	
		
			
				
					|  |  |  |     } else { | 
			
		
	
		
			
				
					|  |  |  |       // neither giver nor recipient are named | 
			
		
	
		
			
				
					|  |  |  |       let peopleInfo; | 
			
		
	
		
			
				
					|  |  |  |       if (giverInfo.displayName === recipientInfo.displayName) { | 
			
		
	
		
			
				
					|  |  |  |         peopleInfo = `between two who are ${giverInfo.displayName}`; | 
			
		
	
		
			
				
					|  |  |  |       } else { | 
			
		
	
		
			
				
					|  |  |  |         peopleInfo = `from ${giverInfo.displayName} to ${recipientInfo.displayName}`; | 
			
		
	
		
			
				
					|  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |       return gaveAmount + " (" + peopleInfo + ")"; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   onClickLoadClaim(jwtId: string) { | 
			
		
	
	
		
			
				
					|  |  | @ -506,7 +555,7 @@ export default class HomeView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |     return unitCode === "HUR" ? (single ? "hour" : "hours") : unitCode; | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   openDialog(giver: GiverInputInfo) { | 
			
		
	
		
			
				
					|  |  |  |   openDialog(giver?: GiverInputInfo) { | 
			
		
	
		
			
				
					|  |  |  |     (this.$refs.customDialog as GiftedDialog).open(giver); | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | 
 |