diff --git a/src/components/ActivityListItem.vue b/src/components/ActivityListItem.vue index 1992443..3291fc1 100644 --- a/src/components/ActivityListItem.vue +++ b/src/components/ActivityListItem.vue @@ -19,14 +19,14 @@ />
-

[POSTER_NAME]

-

[TIMESTAMP]

- +

+ + {{ record.giver.known ? record.giver.displayName : 'Anonymous Giver' }} + +

+

+ {{ friendlyDate }} +

@@ -55,34 +55,35 @@ class="w-28 sm:w-48 text-center bg-white border border-slate-200 rounded p-2 sm:p-3" >
- - - - + Identicon + - - --> +
- - - - + Identicon + - - --> +
@@ -176,6 +185,8 @@ import { Component, Prop, Vue } from "vue-facing-decorator"; import { GiveRecordWithContactInfo } from "../types"; import EntityIcon from "./EntityIcon.vue"; +import { isGiveClaimType, notifyWhyCannotConfirm } from "../libs/util"; +import { containsHiddenDid } from "../libs/endorserServer"; @Component({ components: { @@ -185,6 +196,9 @@ import EntityIcon from "./EntityIcon.vue"; export default class ActivityListItem extends Vue { @Prop() record!: GiveRecordWithContactInfo; @Prop() lastViewedClaimId?: string; + @Prop() isRegistered!: boolean; + @Prop() activeDid!: string; + @Prop() confirmerIdList?: string[]; private formatAmount(claim: unknown): string { const amount = claim.object?.amountOfThisGood @@ -274,5 +288,39 @@ export default class ActivityListItem extends Vue { // Add your timestamp formatting logic here return this.record.timestamp; } + + get canConfirm(): boolean { + if (!this.isRegistered) return false; + if (!isGiveClaimType(this.record.fullClaim?.["@type"])) return false; + if (this.confirmerIdList?.includes(this.activeDid)) return false; + if (this.record.issuerDid === this.activeDid) return false; + if (containsHiddenDid(this.record.fullClaim)) return false; + return true; + } + + handleConfirmClick() { + if (!this.canConfirm) { + notifyWhyCannotConfirm( + this.$notify, + this.isRegistered, + this.record.fullClaim?.["@type"], + this.record, + this.activeDid, + this.confirmerIdList + ); + return; + } + + this.$emit('confirmClaim', this.record); + } + + get friendlyDate(): string { + const date = new Date(this.record.issuedAt); + return date.toLocaleDateString(undefined, { + year: 'numeric', + month: 'short', + day: 'numeric' + }); + } } diff --git a/src/db/tables/settings.ts b/src/db/tables/settings.ts index 69010cb..726a41e 100644 --- a/src/db/tables/settings.ts +++ b/src/db/tables/settings.ts @@ -20,7 +20,7 @@ export type Settings = { // active Decentralized ID activeDid?: string; // only used in the MASTER_SETTINGS_KEY entry - apiServer: string; // API server URL + apiServer?: string; // API server URL filterFeedByNearby?: boolean; // filter by nearby filterFeedByVisible?: boolean; // filter by visible users ie. anyone not hidden diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue index a5eea85..df14c19 100644 --- a/src/views/HomeView.vue +++ b/src/views/HomeView.vue @@ -255,9 +255,13 @@ :key="record.jwtId" :record="record" :lastViewedClaimId="feedLastViewedClaimId" + :isRegistered="isRegistered" + :activeDid="activeDid" + :confirmerIdList="record.confirmerIdList" @loadClaim="onClickLoadClaim" @viewImage="openImageViewer" @cacheImage="cacheImageData" + @confirmClaim="confirmClaim" /> @@ -336,6 +340,7 @@ import { OnboardPage, registerSaveAndActivatePasskey, } from "../libs/util"; +import * as serverUtil from "../libs/endorserServer"; // import { fa0 } from "@fortawesome/free-solid-svg-icons"; interface GiveRecordWithContactInfo extends GiveSummaryRecord { @@ -461,6 +466,7 @@ export default class HomeView extends Vue { if (resp.status === 200) { await updateAccountSettings(this.activeDid, { isRegistered: true, + ...await retrieveSettingsForActiveAccount() }); this.isRegistered = true; } @@ -904,5 +910,61 @@ export default class HomeView extends Vue { this.selectedImage = imageUrl; this.isImageViewerOpen = true; } + + async confirmClaim(record: GiveRecordWithContactInfo) { + this.$notify( + { + group: "modal", + type: "confirm", + title: "Confirm", + text: "Do you personally confirm that this is true?", + onYes: async () => { + const goodClaim = serverUtil.removeSchemaContext( + serverUtil.removeVisibleToDids( + serverUtil.addLastClaimOrHandleAsIdIfMissing( + record.fullClaim, + record.jwtId, + record.handleId + ) + ) + ); + + const confirmationClaim = { + "@context": "https://schema.org", + "@type": "AgreeAction", + object: goodClaim + }; + + const result = await serverUtil.createAndSubmitClaim( + confirmationClaim, + this.activeDid, + this.apiServer, + this.axios + ); + + if (result.type === "success") { + this.$notify({ + group: "alert", + type: "success", + title: "Success", + text: "Confirmation submitted." + }, 3000); + + // Refresh the feed to show updated confirmation status + await this.updateAllFeed(); + } else { + console.error("Error submitting confirmation:", result); + this.$notify({ + group: "alert", + type: "danger", + title: "Error", + text: "There was a problem submitting the confirmation." + }, 5000); + } + } + }, + -1 + ); + } }