@ -1,9 +1,12 @@
/ * * * D a t a E x p o r t S e c t i o n C o m p o n e n t * * P r o v i d e s U I a n d f u n c t i o n a l i t y f o r
/ * * * D a t a E x p o r t S e c t i o n C o m p o n e n t * * P r o v i d e s U I a n d f u n c t i o n a l i t y f o r
exporting user data and backing up identifier seeds . * Includes buttons for seed
exporting user data and backing up identifier seeds . * Includes buttons for seed
backup and database export , with platform - specific download instructions . * *
backup and database export , with platform - specific download instructions . * *
@ component * @ displayName DataExportSection * @ example * ` ` ` vue *
Features : * - Platform - specific export handling ( web vs . native ) * - Proper
resource cleanup for blob URLs * - Robust error handling with user - friendly
messages * - Conditional UI based on platform capabilities * * @ component *
@ displayName DataExportSection * @ example * ` ` ` vue *
< DataExportSection :active-did ="currentDid" / >
< DataExportSection :active-did ="currentDid" / >
* ` ` ` */
* ` ` ` * * @author Matthew Raymer * @since 2025-01-25 * @version 1.1.0 * /
< template >
< template >
< div
< div
@ -26,11 +29,14 @@ backup and database export, with platform-specific download instructions. * *
>
>
Download Contacts
Download Contacts
< / button >
< / button >
<!-- Hidden download link for web platform - always rendered for ref access -- >
< a
< a
v - if = "isWebPlatform && downloadUrl"
v - if = "isWebPlatform"
ref = "downloadLink"
ref = "downloadLink"
: href = "downloadUrl"
: href = "downloadUrl"
: download = "fileName"
: download = "fileName"
: class = "{ hidden: !downloadUrl }"
class = "block w-full text-center text-md bg-gradient-to-b from-green-500 to-green-800 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mb-6"
class = "block w-full text-center text-md bg-gradient-to-b from-green-500 to-green-800 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mb-6"
>
>
If no download happened yet , click again here to download now .
If no download happened yet , click again here to download now .
@ -97,8 +103,11 @@ export default class DataExportSection extends Vue {
/ * *
/ * *
* Notification helper for consistent notification patterns
* Notification helper for consistent notification patterns
* Created as a getter to ensure $notify is available when called
* /
* /
notify = createNotifyHelpers ( this . $notify ) ;
get notify ( ) {
return createNotifyHelpers ( this . $notify ) ;
}
/ * *
/ * *
* NOTE : PlatformServiceMixin provides both concise helpers ( e . g . $contacts , capabilities )
* NOTE : PlatformServiceMixin provides both concise helpers ( e . g . $contacts , capabilities )
@ -135,6 +144,7 @@ export default class DataExportSection extends Vue {
beforeUnmount ( ) {
beforeUnmount ( ) {
if ( this . downloadUrl && this . isWebPlatform ) {
if ( this . downloadUrl && this . isWebPlatform ) {
URL . revokeObjectURL ( this . downloadUrl ) ;
URL . revokeObjectURL ( this . downloadUrl ) ;
this . downloadUrl = "" ;
}
}
}
}
@ -183,9 +193,31 @@ export default class DataExportSection extends Vue {
* /
* /
private async handleWebExport ( blob : Blob ) : Promise < void > {
private async handleWebExport ( blob : Blob ) : Promise < void > {
this . downloadUrl = URL . createObjectURL ( blob ) ;
this . downloadUrl = URL . createObjectURL ( blob ) ;
const downloadAnchor = this . $refs . downloadLink as HTMLAnchorElement ;
downloadAnchor . click ( ) ;
try {
setTimeout ( ( ) => URL . revokeObjectURL ( this . downloadUrl ) , 1000 ) ;
/ / W a i t f o r n e x t t i c k t o e n s u r e D O M i s u p d a t e d
await this . $nextTick ( ) ;
const downloadAnchor = this . $refs . downloadLink as HTMLAnchorElement ;
if ( ! downloadAnchor ) {
throw new Error ( "Download link element not found. Please try again." ) ;
}
downloadAnchor . click ( ) ;
/ / C l e a n u p t h e U R L a f t e r a d e l a y
setTimeout ( ( ) => {
URL . revokeObjectURL ( this . downloadUrl ) ;
this . downloadUrl = "" ;
} , 1000 ) ;
} catch ( error ) {
/ / C l e a n u p t h e U R L o n e r r o r
if ( this . downloadUrl ) {
URL . revokeObjectURL ( this . downloadUrl ) ;
this . downloadUrl = "" ;
}
throw error ;
}
}
}
/ * *
/ * *