@ -253,6 +253,17 @@ import {
import * as libsUtil from "../libs/util" ;
import EntityIcon from "../components/EntityIcon.vue" ;
/ * *
* DIDView Component
*
* Displays detailed information about a DID ( Decentralized Identifier ) entity , including :
* - Basic identity information ( name , profile image )
* - Contact management controls ( visibility , registration status )
* - Associated claims and their details
*
* The view supports both viewing one 's own DID and other contacts' DIDs .
* It provides infinite scrolling for claims and interactive controls for contact management .
* /
@ Component ( {
components : {
EntityIcon ,
@ -287,51 +298,111 @@ export default class DIDView extends Vue {
didInfoForContact = didInfoForContact ;
displayAmount = displayAmount ;
/ * *
* Initializes the view with DID information
*
* Workflow :
* 1. Retrieves active account settings ( DID and API server )
* 2. Determines which DID to display from URL params or defaults to active DID
* 3. Loads contact information if available
* 4. Loads associated claims
* 5. Determines if viewing own DID
* /
async mounted ( ) {
await this . initializeSettings ( ) ;
await this . determineDIDToDisplay ( ) ;
if ( this . viewingDid ) {
await this . loadContactInformation ( ) ;
await this . loadClaimsAbout ( ) ;
await this . checkIfOwnDID ( ) ;
}
}
/ * *
* Initializes component settings from active account
* /
private async initializeSettings ( ) {
const settings = await retrieveSettingsForActiveAccount ( ) ;
this . activeDid = settings . activeDid || "" ;
this . apiServer = settings . apiServer || "" ;
}
/ * *
* Determines which DID to display based on URL parameters
* Falls back to active DID if no parameter provided
* /
private async determineDIDToDisplay ( ) {
const pathParam = window . location . pathname . substring ( "/did/" . length ) ;
let showDid = pathParam ;
if ( ! showDid ) {
showDid = this . activeDid ;
if ( showDid ) {
this . $notify (
{
group : "alert" ,
type : "toast" ,
title : "Your Info" ,
text : "No user was specified so showing your info." ,
} ,
3000 ,
) ;
this . notifyDefaultToActiveDID ( ) ;
}
}
if ( showDid ) {
this . viewingDid = decodeURIComponent ( showDid ) ;
this . contactFromDid = await db . contacts . get ( this . viewingDid ) ;
if ( this . contactFromDid ) {
this . contactYaml = yaml . dump ( this . contactFromDid ) ;
}
await this . loadClaimsAbout ( ) ;
}
}
/ * *
* Notifies user that we ' re showing their DID info by default
* /
private notifyDefaultToActiveDID ( ) {
this . $notify (
{
group : "alert" ,
type : "toast" ,
title : "Your Info" ,
text : "No user was specified so showing your info." ,
} ,
3000 ,
) ;
}
const allAccountDids = await libsUtil . retrieveAccountDids ( ) ;
this . isMyDid = allAccountDids . includes ( this . viewingDid ) ;
/ * *
* Loads contact information for the viewing DID
* Updates contact YAML representation if contact exists
* /
private async loadContactInformation ( ) {
if ( ! this . viewingDid ) return ;
this . contactFromDid = await db . contacts . get ( this . viewingDid ) ;
if ( this . contactFromDid ) {
this . contactYaml = yaml . dump ( this . contactFromDid ) ;
}
}
/ * *
* Data loader used by infinite scroller
* @ param payload is the flag from the InfiniteScroll indicating if it should load
* * /
* Checks if the viewing DID belongs to the current user
* /
private async checkIfOwnDID ( ) {
if ( ! this . viewingDid ) return ;
const allAccountDids = await libsUtil . retrieveAccountDids ( ) ;
this . isMyDid = allAccountDids . includes ( this . viewingDid ) ;
}
/ * *
* Loads additional claims when user scrolls to bottom
* Used by infinite scroll component to implement pagination
*
* @ param payload - Boolean indicating if more data should be loaded
* /
async loadMoreData ( payload : boolean ) {
if ( this . claims . length > 0 && ! this . hitEnd && payload ) {
this . loadClaimsAbout ( ) ;
}
}
/ / p r o m p t w i t h c o n f i r m a t i o n i f t h e y w a n t t o d e l e t e a c o n t a c t
/ * *
* Prompts user to confirm contact deletion
* Shows additional warning if contact has visibility permissions
*
* @ param contact - Contact object to be deleted
* /
confirmDeleteContact ( contact : Contact ) {
let message =
"Are you sure you want to remove " +
@ -355,6 +426,11 @@ export default class DIDView extends Vue {
) ;
}
/ * *
* Deletes contact from local database and navigates back to contacts list
*
* @ param contact - Contact object to be deleted
* /
async deleteContact ( contact : Contact ) {
await db . open ( ) ;
await db . contacts . delete ( contact . did ) ;
@ -370,7 +446,12 @@ export default class DIDView extends Vue {
this . $router . push ( { name : "contacts" } ) ;
}
/ / c o n f i r m t o r e g i s t e r a n e w c o n t a c t
/ * *
* Prompts user to confirm registering a contact
* Shows additional warning if contact is already registered
*
* @ param contact - Contact to be registered
* /
async confirmRegister ( contact : Contact ) {
this . $notify (
{
@ -392,7 +473,12 @@ export default class DIDView extends Vue {
) ;
}
/ / n o t e t h a t t h i s i s a l s o i n C o n t a c t V i e w . v u e
/ * *
* Registers a contact with the endorser server
* Updates local database with registration status
*
* @ param contact - Contact to register
* /
async register ( contact : Contact ) {
this . $notify ( { group : "alert" , type : "toast" , title : "Sent..." } , 1000 ) ;
@ -458,6 +544,11 @@ export default class DIDView extends Vue {
}
}
/ * *
* Loads claims that involve the viewed DID
* Implements pagination using beforeId parameter
* Updates loading state and hit - end status
* /
public async loadClaimsAbout ( ) {
if ( ! this . viewingDid ) {
console . error ( "This should never be called without a DID." ) ;
@ -516,6 +607,11 @@ export default class DIDView extends Vue {
}
}
/ * *
* Navigates to detailed claim view
*
* @ param jwtId - JWT ID of the claim to view
* /
onClickLoadClaim ( jwtId : string ) {
const route = {
path : "/claim/" + encodeURIComponent ( jwtId ) ,
@ -523,6 +619,13 @@ export default class DIDView extends Vue {
this . $router . push ( route ) ;
}
/ * *
* Extracts and formats claim amount information
* Handles different claim types ( GiveAction , Offer )
*
* @ param claim - Claim object to process
* @ returns Formatted amount string or empty string if no amount
* /
public claimAmount ( claim : GenericVerifiableCredential ) {
if ( claim . claimType === "GiveAction" ) {
const giveClaim = claim . claim as GiveVerifiableCredential ;
@ -551,11 +654,23 @@ export default class DIDView extends Vue {
return "" ;
}
/ * *
* Extracts claim description
* Falls back to name if no description available
*
* @ param claim - Claim to get description from
* @ returns Description string or empty string
* /
claimDescription ( claim : GenericVerifiableCredential ) {
return claim . claim . name || claim . claim . description || "" ;
}
/ / n o t e t h a t t h i s i s a l s o i n C o n t a c t V i e w . v u e
/ * *
* Prompts user to confirm visibility change for a contact
*
* @ param contact - Contact to modify visibility for
* @ param visibility - New visibility state to set
* /
async confirmSetVisibility ( contact : Contact , visibility : boolean ) {
const visibilityPrompt = visibility
? "Are you sure you want to make your activity visible to them?"
@ -577,7 +692,14 @@ export default class DIDView extends Vue {
) ;
}
/ / n o t e t h a t t h i s i s a l s o i n C o n t a c t V i e w . v u e
/ * *
* Updates contact visibility on server and local database
*
* @ param contact - Contact to update visibility for
* @ param visibility - New visibility state
* @ param showSuccessAlert - Whether to show success notification
* @ returns Boolean indicating success
* /
async setVisibility (
contact : Contact ,
visibility : boolean ,
@ -627,7 +749,12 @@ export default class DIDView extends Vue {
}
}
/ / n o t e t h a t t h i s i s a l s o i n C o n t a c t V i e w . v u e
/ * *
* Checks current visibility status of contact on server
* Updates local database with current status
*
* @ param contact - Contact to check visibility for
* /
async checkVisibility ( contact : Contact ) {
const url =
this . apiServer +