@ -1,16 +1,9 @@
/ * *
* Data Export Section Component
*
* Provides UI and functionality for exporting user data and backing up identifier seeds .
* Includes buttons for seed backup and database export , with platform - specific download instructions .
*
* @ component
* @ displayName DataExportSection
* @ example
* ` ` ` vue
* < DataExportSection :active-did ="currentDid" / >
* ` ` `
* /
/ * * * 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
backup and database export , with platform - specific download instructions . * *
@ component * @ displayName DataExportSection * @ example * ` ` ` vue *
< DataExportSection :active-did ="currentDid" / >
* ` ` ` */
< template >
< div
@ -36,28 +29,24 @@
( excluding Identifier Data )
< / button >
< a
v - if = "platformService?.needsSecondaryDownloadLink()"
ref = "downloadLink"
: class = "computedDownloadLinkClassNames()"
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 .
< / a >
< div class = "mt-4" v-if ="showPlatformInstructions" >
< p >
After the download , you can save the file in your preferred storage
location .
< div
v - if = "platformService?.getExportInstructions().length > 0"
class = "mt-4"
>
< p
v - for = "instruction in platformService?.getExportInstructions()"
: key = "instruction"
class = "list-disc list-outside ml-4"
>
{ { instruction } }
< / p >
< ul >
< li v-if ="platformService.isCapacitor() && isIOS" class="list-disc list-outside ml-4" >
On iOS : Choose "More..." and select a place in iCloud , or go "Back"
and save to another location .
< / li >
< li v-if ="platformService.isCapacitor() && !isIOS" class="list-disc list-outside ml-4" >
On Android : Choose "Open" and then share
< font -awesome icon = "share-nodes" class = "fa-fw" / >
to your prefered place .
< / li >
< / ul >
< / div >
< / div >
< / template >
@ -100,75 +89,72 @@ export default class DataExportSection extends Vue {
/ * *
* Platform service instance for platform - specific operations
* /
private platformService : PlatformService = PlatformServiceFactory . getInstance ( ) ;
/ * *
* Whether the current platform is iOS
* /
private get isIOS ( ) : boolean {
return /iPad|iPhone|iPod/ . test ( navigator . userAgent ) ;
}
/ * *
* Whether to show platform - specific instructions
* /
private get showPlatformInstructions ( ) : boolean {
return this . platformService . isCapacitor ( ) ;
}
private platformService ? : PlatformService ;
/ * *
* Lifecycle hook to clean up resources
* Revokes object URL when component is unmounted ( web platform only )
* /
beforeUnmount ( ) {
if ( this . downloadUrl && this . platformService . isWeb ( ) ) {
if ( this . downloadUrl && this . platformService ? . needsDownloadCleanup ( ) ) {
URL . revokeObjectURL ( this . downloadUrl ) ;
}
}
async mounted ( ) {
this . platformService = await PlatformServiceFactory . getInstance ( ) ;
logger . log (
"DataExportSection mounted on platform:" ,
process . env . VITE_PLATFORM ,
) ;
}
/ * *
* Exports the database to a JSON file
* Uses platform - specific methods for saving the exported data
* Shows success / error notifications to user
*
*
* @ throws { Error } If export fails
* @ emits { Notification } Success or error notification
* /
public async exportDatabase ( ) {
try {
if ( ! this . platformService ) {
this . platformService = await PlatformServiceFactory . getInstance ( ) ;
}
logger . log (
"Starting database export on platform:" ,
process . env . VITE_PLATFORM ,
) ;
const blob = await db . export ( { prettyJson : true } ) ;
const fileName = ` ${ db . name } -backup.json ` ;
logger . log ( "Database export details:" , {
fileName ,
blobSize : ` ${ blob . size } bytes ` ,
platform : process . env . VITE_PLATFORM ,
} ) ;
if ( this . platformService . isWeb ( ) ) {
/ / W e b p l a t f o r m : U s e d o w n l o a d l i n k
this . downloadUrl = URL . createObjectURL ( blob ) ;
const downloadAnchor = this . $refs . downloadLink as HTMLAnchorElement ;
downloadAnchor . href = this . downloadUrl ;
downloadAnchor . download = fileName ;
downloadAnchor . click ( ) ;
setTimeout ( ( ) => URL . revokeObjectURL ( this . downloadUrl ) , 1000 ) ;
} else if ( this . platformService . isCapacitor ( ) ) {
/ / C a p a c i t o r p l a t f o r m : W r i t e t o a p p d i r e c t o r y
const content = await blob . text ( ) ;
await this . platformService . writeFile ( fileName , content ) ;
} else {
/ / O t h e r p l a t f o r m s : U s e p l a t f o r m s e r v i c e
await this . platformService . writeFile ( fileName , await blob . text ( ) ) ;
}
await this . platformService . exportDatabase ( blob , fileName ) ;
logger . log ( "Database export completed successfully:" , {
fileName ,
platform : process . env . VITE_PLATFORM ,
} ) ;
this . $notify (
{
group : "alert" ,
type : "success" ,
title : "Export Successful" ,
text : this . platformService . isWeb ( )
? "See your downloads directory for the backup. It is in the Dexie format."
: "The backup has been saved to your device." ,
text : this . platformService . getExportSuccessMessage ( ) ,
} ,
- 1 ,
) ;
} catch ( error ) {
logger . error ( "Export Error:" , error ) ;
logger . error ( "Database export failed:" , {
error ,
platform : process . env . VITE_PLATFORM ,
} ) ;
this . $notify (
{
group : "alert" ,
@ -187,7 +173,8 @@ export default class DataExportSection extends Vue {
* /
public computedStartDownloadLinkClassNames ( ) {
return {
hidden : this . downloadUrl && this . platformService . isWeb ( ) ,
hidden :
this . downloadUrl && this . platformService ? . needsSecondaryDownloadLink ( ) ,
} ;
}
@ -197,7 +184,9 @@ export default class DataExportSection extends Vue {
* /
public computedDownloadLinkClassNames ( ) {
return {
hidden : ! this . downloadUrl || ! this . platformService . isWeb ( ) ,
hidden :
! this . downloadUrl ||
! this . platformService ? . needsSecondaryDownloadLink ( ) ,
} ;
}
}