Browse Source

refine claim certificate view

split_build_process
Trent Larson 1 month ago
parent
commit
6d1681cb07
  1. 10
      src/libs/endorserServer.ts
  2. 73
      src/views/ClaimCertificateView.vue
  3. 12
      src/views/ClaimView.vue

10
src/libs/endorserServer.ts

@ -476,6 +476,16 @@ export function didInfo(
return didInfoForContact(did, activeDid, contact, allMyDids).displayName; return didInfoForContact(did, activeDid, contact, allMyDids).displayName;
} }
/**
* return text description without any references to "you" as user
*/
export function didInfoForCertificate(
did: string | undefined,
contacts: Contact[],
): string {
return didInfoForContact(did, undefined, contactForDid(did, contacts), []).displayName;
}
let passkeyAccessToken: string = ""; let passkeyAccessToken: string = "";
let passkeyTokenExpirationEpochSeconds: number = 0; let passkeyTokenExpirationEpochSeconds: number = 0;

73
src/views/ClaimCertificateView.vue

@ -21,8 +21,8 @@ import { Component, Vue } from "vue-facing-decorator";
import { nextTick } from "vue"; import { nextTick } from "vue";
import QRCode from "qrcode"; import QRCode from "qrcode";
import { NotificationIface } from "@/constants/app"; import { APP_SERVER, NotificationIface } from "@/constants/app";
import { retrieveSettingsForActiveAccount } from "@/db/index"; import { db, retrieveSettingsForActiveAccount } from "@/db/index";
import * as endorserServer from "@/libs/endorserServer"; import * as endorserServer from "@/libs/endorserServer";
@Component @Component
@ -56,7 +56,9 @@ export default class ClaimViewCertificate extends Vue {
if (response.ok) { if (response.ok) {
this.claimData = await response.json(); this.claimData = await response.json();
await nextTick(); // Wait for the DOM to update await nextTick(); // Wait for the DOM to update
this.drawCanvas(); if (this.claimData) {
this.drawCanvas(this.claimData);
}
} else { } else {
throw new Error(`Error fetching claim: ${response.statusText}`); throw new Error(`Error fetching claim: ${response.statusText}`);
} }
@ -71,7 +73,12 @@ export default class ClaimViewCertificate extends Vue {
} }
} }
drawCanvas() { async drawCanvas(
claimData: endorserServer.GenericCredWrapper<endorserServer.GenericVerifiableCredential>,
) {
await db.open();
const allContacts = await db.contacts.toArray();
const canvas = this.$refs.claimCanvas as HTMLCanvasElement; const canvas = this.$refs.claimCanvas as HTMLCanvasElement;
if (canvas) { if (canvas) {
const CANVAS_WIDTH = 1100; const CANVAS_WIDTH = 1100;
@ -96,21 +103,43 @@ export default class ClaimViewCertificate extends Vue {
ctx.font = "bold 20px Arial"; ctx.font = "bold 20px Arial";
const claimTypeText = const claimTypeText =
this.endorserServer.capitalizeAndInsertSpacesBeforeCaps( this.endorserServer.capitalizeAndInsertSpacesBeforeCaps(
this.claimData.claimType, claimData.claimType || "",
); );
const claimTypeWidth = ctx.measureText(claimTypeText).width; const claimTypeWidth = ctx.measureText(claimTypeText).width;
ctx.fillText( ctx.fillText(
claimTypeText, claimTypeText,
(CANVAS_WIDTH - claimTypeWidth) / 2, // Center horizontally (CANVAS_WIDTH - claimTypeWidth) / 2, // Center horizontally
CANVAS_HEIGHT * 0.35, CANVAS_HEIGHT * 0.33,
);
if (claimData.claim.agent) {
const presentedText = "Presented to ";
ctx.font = "14px Arial";
const presentedWidth = ctx.measureText(presentedText).width;
ctx.fillText(
presentedText,
(CANVAS_WIDTH - presentedWidth) / 2, // Center horizontally
CANVAS_HEIGHT * 0.37,
);
const agentText = endorserServer.didInfoForCertificate(
claimData.claim.agent,
allContacts,
);
ctx.font = "bold 20px Arial";
const agentWidth = ctx.measureText(agentText).width;
ctx.fillText(
agentText,
(CANVAS_WIDTH - agentWidth) / 2, // Center horizontally
CANVAS_HEIGHT * 0.4,
); );
}
const descriptionText = const descriptionText =
this.claimData.claim.description || this.claimData.claim.name; claimData.claim.name || claimData.claim.description;
if (descriptionText) { if (descriptionText) {
const descriptionLine = const descriptionLine =
descriptionText.length > 50 descriptionText.length > 50
? descriptionText.substring(0, 47) + "..." ? descriptionText.substring(0, 85) + "..."
: descriptionText; : descriptionText;
ctx.font = "14px Arial"; ctx.font = "14px Arial";
const descriptionWidth = ctx.measureText(descriptionLine).width; const descriptionWidth = ctx.measureText(descriptionLine).width;
@ -121,26 +150,38 @@ export default class ClaimViewCertificate extends Vue {
); );
} }
// Draw claim issuer & recipient
if (claimData.issuer) {
ctx.font = "14px Arial";
const issuerText =
"Issued by " +
endorserServer.didInfoForCertificate(
claimData.issuer,
allContacts,
);
ctx.fillText(issuerText, CANVAS_WIDTH * 0.3, CANVAS_HEIGHT * 0.6);
}
// Draw claim ID // Draw claim ID
ctx.font = "14px Arial"; ctx.font = "14px Arial";
ctx.fillText(this.claimId, CANVAS_WIDTH * 0.3, CANVAS_HEIGHT * 0.62); ctx.fillText(this.claimId, CANVAS_WIDTH * 0.3, CANVAS_HEIGHT * 0.7);
ctx.fillText( ctx.fillText(
"via EndorserSearch.com", "via EndorserSearch.com",
CANVAS_WIDTH * 0.3, CANVAS_WIDTH * 0.3,
CANVAS_HEIGHT * 0.65, CANVAS_HEIGHT * 0.73,
); );
// Generate and draw QR code // Generate and draw QR code
const qrCodeCanvas = document.createElement("canvas"); const qrCodeCanvas = document.createElement("canvas");
await QRCode.toCanvas(qrCodeCanvas, window.location.href, { await QRCode.toCanvas(
qrCodeCanvas,
APP_SERVER + "/claim/" + this.claimId,
{
width: 150, width: 150,
color: { light: "#0000" /* Transparent background */ }, color: { light: "#0000" /* Transparent background */ },
}); },
ctx.drawImage(
qrCodeCanvas,
CANVAS_WIDTH * 0.57,
CANVAS_HEIGHT * 0.55,
); );
ctx.drawImage(qrCodeCanvas, CANVAS_WIDTH * 0.6, CANVAS_HEIGHT * 0.55);
}; };
} }
} }

12
src/views/ClaimView.vue

@ -20,6 +20,7 @@
<div class="bg-slate-100 rounded-md overflow-hidden px-4 py-3 mb-4"> <div class="bg-slate-100 rounded-md overflow-hidden px-4 py-3 mb-4">
<div class="block flex gap-4 overflow-hidden"> <div class="block flex gap-4 overflow-hidden">
<div class="overflow-hidden"> <div class="overflow-hidden">
<div class="flex justify-between">
<h2 class="text-md font-bold"> <h2 class="text-md font-bold">
{{ capitalizeAndInsertSpacesBeforeCaps(veriClaim.claimType) }} {{ capitalizeAndInsertSpacesBeforeCaps(veriClaim.claimType) }}
<button <button
@ -38,6 +39,17 @@
<fa icon="pen" class="text-sm text-blue-500 ml-2 mb-1" /> <fa icon="pen" class="text-sm text-blue-500 ml-2 mb-1" />
</button> </button>
</h2> </h2>
<!--
<div>
<router-link
:to="'/claim-cert/' + encodeURIComponent(veriClaim.id)"
class="text-blue-500 mt-2"
>
<fa icon="square" class="text-white bg-yellow-500 p-1" />
</router-link>
</div>
-->
</div>
<div class="text-sm"> <div class="text-sm">
<div data-testId="description"> <div data-testId="description">
<fa icon="message" class="fa-fw text-slate-400" /> <fa icon="message" class="fa-fw text-slate-400" />

Loading…
Cancel
Save