|  |  | @ -70,8 +70,7 @@ | 
			
		
	
		
			
				
					|  |  |  | </template> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | <script lang="ts"> | 
			
		
	
		
			
				
					|  |  |  | import * as R from "ramda"; | 
			
		
	
		
			
				
					|  |  |  | import { Options, Vue } from "vue-class-component"; | 
			
		
	
		
			
				
					|  |  |  | import { Component, Vue } from "vue-facing-decorator"; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | import GiftedDialog from "@/components/GiftedDialog.vue"; | 
			
		
	
		
			
				
					|  |  |  | import { db, accountsDB } from "@/db"; | 
			
		
	
	
		
			
				
					|  |  | @ -83,7 +82,7 @@ import { Contact } from "@/db/tables/contacts"; | 
			
		
	
		
			
				
					|  |  |  | import AlertMessage from "@/components/AlertMessage"; | 
			
		
	
		
			
				
					|  |  |  | import QuickNav from "@/components/QuickNav"; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | @Options({ | 
			
		
	
		
			
				
					|  |  |  | @Component({ | 
			
		
	
		
			
				
					|  |  |  |   components: { GiftedDialog, AlertMessage, QuickNav }, | 
			
		
	
		
			
				
					|  |  |  | }) | 
			
		
	
		
			
				
					|  |  |  | export default class HomeView extends Vue { | 
			
		
	
	
		
			
				
					|  |  | @ -99,7 +98,6 @@ export default class HomeView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |   alertTitle = ""; | 
			
		
	
		
			
				
					|  |  |  |   alertMessage = ""; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   // 'created' hook runs when the Vue instance is first created | 
			
		
	
		
			
				
					|  |  |  |   async created() { | 
			
		
	
		
			
				
					|  |  |  |     try { | 
			
		
	
		
			
				
					|  |  |  |       await accountsDB.open(); | 
			
		
	
	
		
			
				
					|  |  | @ -119,6 +117,28 @@ export default class HomeView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   public async buildHeaders() { | 
			
		
	
		
			
				
					|  |  |  |     const headers = { "Content-Type": "application/json" }; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     if (this.activeDid) { | 
			
		
	
		
			
				
					|  |  |  |       await accountsDB.open(); | 
			
		
	
		
			
				
					|  |  |  |       const allAccounts = await accountsDB.accounts.toArray(); | 
			
		
	
		
			
				
					|  |  |  |       const account = allAccounts.find((acc) => acc.did === this.activeDid); | 
			
		
	
		
			
				
					|  |  |  |       const identity = JSON.parse(account?.identity || "null"); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |       if (!identity) { | 
			
		
	
		
			
				
					|  |  |  |         throw new Error( | 
			
		
	
		
			
				
					|  |  |  |           "An ID is chosen but there are no keys for it so it cannot be used to talk with the service." | 
			
		
	
		
			
				
					|  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |       headers["Authorization"] = "Bearer " + (await accessToken(identity)); | 
			
		
	
		
			
				
					|  |  |  |     } else { | 
			
		
	
		
			
				
					|  |  |  |       // it's OK without auth... we just won't get any identifiers | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     return headers; | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   updateAllFeed = async () => { | 
			
		
	
		
			
				
					|  |  |  |     this.isHiddenSpinner = false; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -126,7 +146,6 @@ export default class HomeView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |       .then(async (results) => { | 
			
		
	
		
			
				
					|  |  |  |         if (results.data.length > 0) { | 
			
		
	
		
			
				
					|  |  |  |           this.feedData = this.feedData.concat(results.data); | 
			
		
	
		
			
				
					|  |  |  |           //console.log("Feed data:", this.feedData); | 
			
		
	
		
			
				
					|  |  |  |           this.feedAllLoaded = results.hitLimit; | 
			
		
	
		
			
				
					|  |  |  |           this.feedPreviousOldestId = | 
			
		
	
		
			
				
					|  |  |  |             results.data[results.data.length - 1].jwtId; | 
			
		
	
	
		
			
				
					|  |  | @ -134,7 +153,6 @@ export default class HomeView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |             this.feedLastViewedId == null || | 
			
		
	
		
			
				
					|  |  |  |             this.feedLastViewedId < results.data[0].jwtId | 
			
		
	
		
			
				
					|  |  |  |           ) { | 
			
		
	
		
			
				
					|  |  |  |             // save it to storage | 
			
		
	
		
			
				
					|  |  |  |             await db.open(); | 
			
		
	
		
			
				
					|  |  |  |             db.settings.update(MASTER_SETTINGS_KEY, { | 
			
		
	
		
			
				
					|  |  |  |               lastViewedClaimId: results.data[0].jwtId, | 
			
		
	
	
		
			
				
					|  |  | @ -154,41 +172,26 @@ export default class HomeView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |   }; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   retrieveClaims = async (endorserApiServer, identifier, beforeId) => { | 
			
		
	
		
			
				
					|  |  |  |     //const afterQuery = afterId == null ? "" : "&afterId=" + afterId; | 
			
		
	
		
			
				
					|  |  |  |     const beforeQuery = beforeId == null ? "" : "&beforeId=" + beforeId; | 
			
		
	
		
			
				
					|  |  |  |     const headers = { "Content-Type": "application/json" }; | 
			
		
	
		
			
				
					|  |  |  |     if (this.activeDid) { | 
			
		
	
		
			
				
					|  |  |  |       const account = R.find( | 
			
		
	
		
			
				
					|  |  |  |         (acc) => acc.did === this.activeDid, | 
			
		
	
		
			
				
					|  |  |  |         this.allAccounts | 
			
		
	
		
			
				
					|  |  |  |       ); | 
			
		
	
		
			
				
					|  |  |  |       const identity = JSON.parse(account?.identity || "null"); | 
			
		
	
		
			
				
					|  |  |  |       if (!identity) { | 
			
		
	
		
			
				
					|  |  |  |         throw new Error("No identity found."); | 
			
		
	
		
			
				
					|  |  |  |     const response = await fetch( | 
			
		
	
		
			
				
					|  |  |  |       this.apiServer + "/api/v2/report/gives?" + beforeQuery, | 
			
		
	
		
			
				
					|  |  |  |       { | 
			
		
	
		
			
				
					|  |  |  |         method: "GET", | 
			
		
	
		
			
				
					|  |  |  |         headers: await buildHeaders(), | 
			
		
	
		
			
				
					|  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |       const token = await accessToken(identity); | 
			
		
	
		
			
				
					|  |  |  |       headers["Authorization"] = "Bearer " + token; | 
			
		
	
		
			
				
					|  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     if (response.status !== 200) { | 
			
		
	
		
			
				
					|  |  |  |       throw await response.text(); | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     const results = await response.json(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     if (results.data) { | 
			
		
	
		
			
				
					|  |  |  |       return results; | 
			
		
	
		
			
				
					|  |  |  |     } else { | 
			
		
	
		
			
				
					|  |  |  |       // it's OK without auth... we just won't get any identifiers | 
			
		
	
		
			
				
					|  |  |  |       throw JSON.stringify(results); | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     return fetch(this.apiServer + "/api/v2/report/gives?" + beforeQuery, { | 
			
		
	
		
			
				
					|  |  |  |       method: "GET", | 
			
		
	
		
			
				
					|  |  |  |       headers: headers, | 
			
		
	
		
			
				
					|  |  |  |     }) | 
			
		
	
		
			
				
					|  |  |  |       .then(async (response) => { | 
			
		
	
		
			
				
					|  |  |  |         if (response.status !== 200) { | 
			
		
	
		
			
				
					|  |  |  |           const details = await response.text(); | 
			
		
	
		
			
				
					|  |  |  |           throw details; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         return response.json(); | 
			
		
	
		
			
				
					|  |  |  |       }) | 
			
		
	
		
			
				
					|  |  |  |       .then((results) => { | 
			
		
	
		
			
				
					|  |  |  |         if (results.data) { | 
			
		
	
		
			
				
					|  |  |  |           return results; | 
			
		
	
		
			
				
					|  |  |  |         } else { | 
			
		
	
		
			
				
					|  |  |  |           throw JSON.stringify(results); | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |       }); | 
			
		
	
		
			
				
					|  |  |  |   }; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   giveDescription(giveRecord) { | 
			
		
	
	
		
			
				
					|  |  | @ -235,6 +238,7 @@ export default class HomeView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |   openDialog(giver) { | 
			
		
	
		
			
				
					|  |  |  |     this.$refs.customDialog.open(giver); | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   handleDialogResult(result) { | 
			
		
	
		
			
				
					|  |  |  |     if (result.action === "confirm") { | 
			
		
	
		
			
				
					|  |  |  |       return new Promise((resolve) => { | 
			
		
	
	
		
			
				
					|  |  | @ -259,21 +263,23 @@ export default class HomeView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |         "You must select an identity before you can record a give."; | 
			
		
	
		
			
				
					|  |  |  |       return; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     if (!description && !hours) { | 
			
		
	
		
			
				
					|  |  |  |       this.alertTitle = "Error"; | 
			
		
	
		
			
				
					|  |  |  |       this.alertMessage = | 
			
		
	
		
			
				
					|  |  |  |         "You must enter a description or some number of hours."; | 
			
		
	
		
			
				
					|  |  |  |       return; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     const account = R.find( | 
			
		
	
		
			
				
					|  |  |  |       (acc) => acc.did === this.activeDid, | 
			
		
	
		
			
				
					|  |  |  |       this.allAccounts | 
			
		
	
		
			
				
					|  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  |     //console.log("about to parse from", this.activeDid, account?.identity); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     const account = this.allAccounts.find((acc) => acc.did === this.activeDid); | 
			
		
	
		
			
				
					|  |  |  |     const identity = JSON.parse(account?.identity || "null"); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     if (!identity) { | 
			
		
	
		
			
				
					|  |  |  |       throw new Error("No identity found."); | 
			
		
	
		
			
				
					|  |  |  |       throw new Error( | 
			
		
	
		
			
				
					|  |  |  |         "An ID is chosen but there are no keys for it so it cannot be used to talk with the service." | 
			
		
	
		
			
				
					|  |  |  |       ); | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     createAndSubmitGive( | 
			
		
	
		
			
				
					|  |  |  |       this.axios, | 
			
		
	
		
			
				
					|  |  |  |       this.apiServer, | 
			
		
	
	
		
			
				
					|  |  | @ -284,20 +290,18 @@ export default class HomeView extends Vue { | 
			
		
	
		
			
				
					|  |  |  |       hours | 
			
		
	
		
			
				
					|  |  |  |     ) | 
			
		
	
		
			
				
					|  |  |  |       .then((result) => { | 
			
		
	
		
			
				
					|  |  |  |         if (result.status != 201 || result.data?.error) { | 
			
		
	
		
			
				
					|  |  |  |         const error = result.data?.error; | 
			
		
	
		
			
				
					|  |  |  |         if (result.status !== 201 || error) { | 
			
		
	
		
			
				
					|  |  |  |           console.log("Error with give result:", result); | 
			
		
	
		
			
				
					|  |  |  |           this.alertTitle = "Error"; | 
			
		
	
		
			
				
					|  |  |  |           this.alertMessage = | 
			
		
	
		
			
				
					|  |  |  |             result.data?.error?.message || | 
			
		
	
		
			
				
					|  |  |  |             "There was an error recording the give."; | 
			
		
	
		
			
				
					|  |  |  |             error?.message || "There was an error recording the give."; | 
			
		
	
		
			
				
					|  |  |  |         } else { | 
			
		
	
		
			
				
					|  |  |  |           this.alertTitle = "Success"; | 
			
		
	
		
			
				
					|  |  |  |           this.alertMessage = "That gift was recorded."; | 
			
		
	
		
			
				
					|  |  |  |           //this.updateAllFeed(); // full update is overkill but we should show something | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |       }) | 
			
		
	
		
			
				
					|  |  |  |       .catch((e) => { | 
			
		
	
		
			
				
					|  |  |  |         // axios throws errors on 400 responses | 
			
		
	
		
			
				
					|  |  |  |         console.log("Error with give caught:", e); | 
			
		
	
		
			
				
					|  |  |  |         this.alertTitle = "Error"; | 
			
		
	
		
			
				
					|  |  |  |         this.alertMessage = | 
			
		
	
	
		
			
				
					|  |  | 
 |