Trent Larson
1 year ago
9 changed files with 285 additions and 23 deletions
@ -1,15 +1,231 @@ |
|||
<template> |
|||
<section></section> |
|||
<!-- QUICK NAV --> |
|||
<nav id="QuickNav" class="fixed bottom-0 left-0 right-0 bg-slate-200 z-50"> |
|||
<ul class="flex text-2xl p-2 gap-2"> |
|||
<!-- Home Feed --> |
|||
<li class="basis-1/5 rounded-md bg-slate-400 text-white"> |
|||
<router-link :to="{ name: 'home' }" class="block text-center py-3 px-1" |
|||
><fa icon="house-chimney" class="fa-fw"></fa |
|||
></router-link> |
|||
</li> |
|||
<!-- Search --> |
|||
<li class="basis-1/5 rounded-md text-slate-500"> |
|||
<router-link |
|||
:to="{ name: 'discover' }" |
|||
class="block text-center py-3 px-1" |
|||
><fa icon="magnifying-glass" class="fa-fw"></fa |
|||
></router-link> |
|||
</li> |
|||
<!-- Projects --> |
|||
<li class="basis-1/5 rounded-md text-slate-500"> |
|||
<router-link |
|||
:to="{ name: 'projects' }" |
|||
class="block text-center py-3 px-1" |
|||
><fa icon="folder-open" class="fa-fw"></fa |
|||
></router-link> |
|||
</li> |
|||
<!-- Contacts --> |
|||
<li class="basis-1/5 rounded-md text-slate-500"> |
|||
<router-link |
|||
:to="{ name: 'contacts' }" |
|||
class="block text-center py-3 px-1" |
|||
><fa icon="users" class="fa-fw"></fa |
|||
></router-link> |
|||
</li> |
|||
<!-- Profile --> |
|||
<li class="basis-1/5 rounded-md text-slate-500"> |
|||
<router-link |
|||
:to="{ name: 'account' }" |
|||
class="block text-center py-3 px-1" |
|||
><fa icon="circle-user" class="fa-fw"></fa |
|||
></router-link> |
|||
</li> |
|||
</ul> |
|||
</nav> |
|||
|
|||
<!-- CONTENT --> |
|||
<section id="Content" class="p-6 pb-24"> |
|||
<h1 id="ViewHeading" class="text-4xl text-center font-light pt-4 mb-8"> |
|||
Feed |
|||
</h1> |
|||
<span :class="{ hidden: isHiddenSpinner }"> |
|||
<fa icon="spinner" class="fa-fw"></fa> |
|||
Loading… |
|||
</span> |
|||
<div> |
|||
<!-- Results List --> |
|||
<ul class=""> |
|||
<li |
|||
class="border-b border-slate-300" |
|||
v-for="record in feedData" |
|||
:key="record.id" |
|||
> |
|||
{{ this.giveDescription(record) }} |
|||
</li> |
|||
</ul> |
|||
</div> |
|||
</section> |
|||
|
|||
<!-- This same popup code is in many files. --> |
|||
<div v-bind:class="computedAlertClassNames()"> |
|||
<button |
|||
class="close-button bg-slate-200 w-8 leading-loose rounded-full absolute top-2 right-2" |
|||
@click="onClickClose()" |
|||
> |
|||
<fa icon="xmark"></fa> |
|||
</button> |
|||
<h4 class="font-bold pr-5">{{ alertTitle }}</h4> |
|||
<p>{{ alertMessage }}</p> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { Options, Vue } from "vue-class-component"; |
|||
import HelloWorld from "@/components/HelloWorld.vue"; // @ is an alias to /src |
|||
|
|||
import { db, accountsDB } from "@/db"; |
|||
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings"; |
|||
import { didInfo } from "@/libs/endorserServer"; |
|||
import { Account } from "@/db/tables/accounts"; |
|||
import { Contact } from "@/db/tables/contacts"; |
|||
import * as R from "ramda"; |
|||
|
|||
@Options({ |
|||
components: { |
|||
HelloWorld, |
|||
}, |
|||
components: {}, |
|||
}) |
|||
export default class HomeView extends Vue {} |
|||
export default class HomeView extends Vue { |
|||
accounts: Array<Account> = []; |
|||
apiServer = ""; |
|||
contacts: Array<Contact> = []; |
|||
feedAllLoaded = false; |
|||
feedData = []; |
|||
feedPreviousOldestId = null; |
|||
isHiddenSpinner = true; |
|||
|
|||
// 'created' hook runs when the Vue instance is first created |
|||
async created() { |
|||
await accountsDB.open(); |
|||
this.accounts = await accountsDB.accounts.toArray(); |
|||
console.log("Accounts:", this.accounts); |
|||
await db.open(); |
|||
this.contacts = await db.contacts.toArray(); |
|||
} |
|||
|
|||
// 'mounted' hook runs after initial render |
|||
async mounted() { |
|||
try { |
|||
await db.open(); |
|||
const settings = await db.settings.get(MASTER_SETTINGS_KEY); |
|||
this.apiServer = settings?.apiServer || ""; |
|||
this.updateAllFeed(); |
|||
} catch (err) { |
|||
console.log("Error in mounted():", err); |
|||
this.alertTitle = "Error"; |
|||
this.alertMessage = |
|||
err.userMessage || |
|||
"There was an error retrieving the latest sweet, sweet action."; |
|||
} |
|||
} |
|||
|
|||
updateAllFeed = async () => { |
|||
this.isHiddenSpinner = false; |
|||
|
|||
await this.retrieveClaims(this.apiServer, null, this.feedPreviousOldestId) |
|||
.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].id; |
|||
} |
|||
}) |
|||
.catch((e) => { |
|||
console.log("Error with feed load:", e); |
|||
this.alertMessage = |
|||
e.userMessage || "There was an error retrieving feed data."; |
|||
}); |
|||
|
|||
this.isHiddenSpinner = true; |
|||
}; |
|||
|
|||
retrieveClaims = async (endorserApiServer, identifier, beforeId) => { |
|||
//const token = await accessToken(identifier) |
|||
//const afterQuery = afterId == null ? "" : "&afterId=" + afterId; |
|||
const beforeQuery = beforeId == null ? "" : "&beforeId=" + beforeId; |
|||
return fetch(this.apiServer + "/api/v2/report/gives?" + beforeQuery, { |
|||
method: "GET", |
|||
headers: { |
|||
"Content-Type": "application/json", |
|||
//"Uport-Push-Token": token, |
|||
}, |
|||
}) |
|||
.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) { |
|||
let claim = giveRecord.fullClaim; |
|||
if (claim.claim) { |
|||
// it's probably a Verified Credential |
|||
claim = claim.claim; |
|||
} |
|||
|
|||
// agent.did is for legacy data, before March 2023 |
|||
const giver = |
|||
claim.agent?.identifier || claim.agent?.did || giveRecord.issuer; |
|||
const giverInfo = giver; //didInfo(giver, identifiers, contacts); |
|||
const gaveAmount = claim.object?.amountOfThisGood |
|||
? this.displayAmount(claim.object.unitCode, claim.object.amountOfThisGood) |
|||
: claim.object; |
|||
// recipient.did is for legacy data, before March 2023 |
|||
const gaveRecipientId = claim.recipient?.identifier || claim.recipient?.did; |
|||
const gaveRecipientInfo = gaveRecipientId |
|||
? " to " + gaveRecipientId //didInfo(gaveRecipientId, identifiers, contacts) |
|||
: ""; |
|||
return giverInfo + " gave " + gaveAmount + gaveRecipientInfo; |
|||
} |
|||
|
|||
displayAmount(code, amt) { |
|||
return "" + amt + " " + this.currencyShortWordForCode(code, amt === 1); |
|||
} |
|||
|
|||
currencyShortWordForCode(unitCode, single) { |
|||
return unitCode === "HUR" ? (single ? "hour" : "hours") : unitCode; |
|||
} |
|||
|
|||
// This same popup code is in many files. |
|||
alertMessage = ""; |
|||
alertTitle = ""; |
|||
public onClickClose() { |
|||
this.alertTitle = ""; |
|||
this.alertMessage = ""; |
|||
} |
|||
public computedAlertClassNames() { |
|||
return { |
|||
hidden: !this.alertMessage, |
|||
"dismissable-alert": true, |
|||
"bg-slate-100": true, |
|||
"p-5": true, |
|||
rounded: true, |
|||
"drop-shadow-lg": true, |
|||
fixed: true, |
|||
"top-3": true, |
|||
"inset-x-3": true, |
|||
"transition-transform": true, |
|||
"ease-in": true, |
|||
"duration-300": true, |
|||
}; |
|||
} |
|||
} |
|||
</script> |
|||
|
Loading…
Reference in new issue