forked from jsnbuchanan/crowd-funder-for-time-pwa
show more succinct info in feed, targeted toward user's visibility
This commit is contained in:
@@ -352,10 +352,54 @@ export function removeVisibleToDids(input: any): any {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
always returns text, maybe UNNAMED_VISIBLE or UNKNOWN_ENTITY
|
||||
export function contactForDid(
|
||||
did: string | undefined,
|
||||
contacts: Contact[],
|
||||
): Contact | undefined {
|
||||
return isEmptyOrHiddenDid(did)
|
||||
? undefined
|
||||
: R.find((c) => c.did === did, contacts);
|
||||
}
|
||||
|
||||
Similar logic is found in endorser-mobile.
|
||||
/**
|
||||
*
|
||||
* Similar logic is found in endorser-mobile.
|
||||
*
|
||||
* @param did
|
||||
* @param activeDid
|
||||
* @param contact
|
||||
* @param allMyDids
|
||||
* @return { known: boolean, displayName: string } where known is true if the display name is some easily-recogizable name, false if it's a generic name like "Someone Anonymous"
|
||||
*/
|
||||
export function didInfoForContact(
|
||||
did: string | undefined,
|
||||
activeDid: string | undefined,
|
||||
contact?: Contact,
|
||||
allMyDids: string[] = [],
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
): { known: boolean; displayName: string } {
|
||||
if (!did) return { displayName: "Someone Anonymous", known: false };
|
||||
if (contact) {
|
||||
return {
|
||||
displayName: contact.name || "Contact With No Name",
|
||||
known: !!contact.name,
|
||||
};
|
||||
} else if (did === activeDid) {
|
||||
return { displayName: "You", known: true };
|
||||
} else {
|
||||
const myId = R.find(R.equals(did), allMyDids);
|
||||
return myId
|
||||
? { displayName: "You (Alt ID)", known: true }
|
||||
: isHiddenDid(did)
|
||||
? { displayName: "Someone Outside Your Network", known: false }
|
||||
: { displayName: "Someone Outside Contacts", known: false };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
always returns text, maybe something like "unnamed" or "unknown"
|
||||
|
||||
Now that we're using more informational didInfoForContact under the covers, we might want to consolidate.
|
||||
**/
|
||||
export function didInfo(
|
||||
did: string | undefined,
|
||||
@@ -363,19 +407,8 @@ export function didInfo(
|
||||
allMyDids: string[],
|
||||
contacts: Contact[],
|
||||
): string {
|
||||
if (!did) return "Someone Anonymous";
|
||||
|
||||
const contact = R.find((c) => c.did === did, contacts);
|
||||
if (contact) {
|
||||
return contact.name || "Contact With No Name";
|
||||
} else {
|
||||
const myId = R.find(R.equals(did), allMyDids);
|
||||
return myId
|
||||
? `You${myId !== activeDid ? " (Alt ID)" : ""}`
|
||||
: isHiddenDid(did)
|
||||
? "Someone Outside Your Network"
|
||||
: "Someone Outside Contacts";
|
||||
}
|
||||
const contact = contactForDid(did, contacts);
|
||||
return didInfoForContact(did, activeDid, contact, allMyDids).displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,12 +28,6 @@ const enterOrStart = async (
|
||||
};
|
||||
|
||||
const routes: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: "/",
|
||||
name: "home",
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "home" */ "../views/HomeView.vue"),
|
||||
},
|
||||
{
|
||||
path: "/account",
|
||||
name: "account",
|
||||
@@ -96,6 +90,12 @@ const routes: Array<RouteRecordRaw> = [
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "help" */ "../views/HelpView.vue"),
|
||||
},
|
||||
{
|
||||
path: "/",
|
||||
name: "home",
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "home" */ "../views/HomeView.vue"),
|
||||
},
|
||||
{
|
||||
path: "/help-notifications",
|
||||
name: "help-notifications",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<QuickNav selected="Profile"></QuickNav>
|
||||
<QuickNav selected="Profile" />
|
||||
<TopMessage />
|
||||
|
||||
<!-- CONTENT -->
|
||||
|
||||
@@ -868,7 +868,7 @@ export default class ContactsView extends Vue {
|
||||
(contact.name || "That unnamed person") +
|
||||
" has been registered.",
|
||||
},
|
||||
-1,
|
||||
5000,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -1190,7 +1190,7 @@ export default class ContactsView extends Vue {
|
||||
title: "Done",
|
||||
text: "Successfully logged time to the server.",
|
||||
},
|
||||
-1,
|
||||
5000,
|
||||
);
|
||||
|
||||
if (fromDid === identity.did) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<QuickNav selected="Profile"></QuickNav>
|
||||
<QuickNav selected="Profile" />
|
||||
<!-- CONTENT -->
|
||||
<section id="Content" class="p-6 pb-24 max-w-3xl mx-auto">
|
||||
<!-- Back -->
|
||||
|
||||
Reference in New Issue
Block a user