Browse Source

feat: Add seed backup tracking with database migration

- Add hasBackedUpSeed boolean flag to Settings interface
- Create database migration 003_add_hasBackedUpSeed_to_settings
- Update SeedBackupView to set flag when user reveals seed phrase
- Modify DataExportSection to conditionally show notification dot
- Implement robust error handling for database operations

The notification dot on the "Backup Identifier Seed" button only
appears while the user hasn't backed up their seed phrase. Once they
visit SeedBackupView and click "Reveal my Seed Phrase", the setting
is persisted and the notification dot disappears.
pull/195/head
Jose Olarte III 2 weeks ago
parent
commit
ec2cab768b
  1. 30
      src/components/DataExportSection.vue
  2. 6
      src/db-sql/migration.ts
  3. 1
      src/db/tables/settings.ts
  4. 17
      src/views/SeedBackupView.vue

30
src/components/DataExportSection.vue

@ -16,6 +16,12 @@ messages * - Conditional UI based on platform capabilities * * @component *
:to="{ name: 'seed-backup' }" :to="{ name: 'seed-backup' }"
:class="backupButtonClasses" :class="backupButtonClasses"
> >
<!-- Notification dot - show while the user has not yet backed up their seed phrase -->
<font-awesome
v-if="!hasBackedUpSeed"
icon="circle"
class="absolute -right-[8px] -top-[8px] text-rose-500 text-[14px] border border-white rounded-full"
></font-awesome>
Backup Identifier Seed Backup Identifier Seed
</router-link> </router-link>
@ -98,6 +104,12 @@ export default class DataExportSection extends Vue {
*/ */
isExporting = false; isExporting = false;
/**
* Flag indicating if the user has backed up their seed phrase
* Used to control the visibility of the notification dot
*/
hasBackedUpSeed = false;
/** /**
* Notification helper for consistent notification patterns * Notification helper for consistent notification patterns
* Created as a getter to ensure $notify is available when called * Created as a getter to ensure $notify is available when called
@ -129,7 +141,7 @@ export default class DataExportSection extends Vue {
* CSS classes for the backup button (router link) * CSS classes for the backup button (router link)
*/ */
get backupButtonClasses(): string { get backupButtonClasses(): string {
return "block w-full text-center text-md bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mb-2 mt-2"; return "block relative w-full text-center text-md bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mb-2 mt-2";
} }
/** /**
@ -218,6 +230,22 @@ export default class DataExportSection extends Vue {
created() { created() {
this.notify = createNotifyHelpers(this.$notify); this.notify = createNotifyHelpers(this.$notify);
this.loadSeedBackupStatus();
}
/**
* Loads the seed backup status from account settings
* Updates the hasBackedUpSeed flag to control notification dot visibility
*/
private async loadSeedBackupStatus(): Promise<void> {
try {
const settings = await this.$accountSettings();
this.hasBackedUpSeed = !!settings.hasBackedUpSeed;
} catch (err: unknown) {
logger.error("Failed to load seed backup status:", err);
// Default to false (show notification dot) if we can't load the setting
this.hasBackedUpSeed = false;
}
} }
} }
</script> </script>

6
src/db-sql/migration.ts

@ -124,6 +124,12 @@ const MIGRATIONS = [
ALTER TABLE contacts ADD COLUMN iViewContent BOOLEAN DEFAULT TRUE; ALTER TABLE contacts ADD COLUMN iViewContent BOOLEAN DEFAULT TRUE;
`, `,
}, },
{
name: "003_add_hasBackedUpSeed_to_settings",
sql: `
ALTER TABLE settings ADD COLUMN hasBackedUpSeed BOOLEAN DEFAULT FALSE;
`,
},
]; ];
/** /**

1
src/db/tables/settings.ts

@ -29,6 +29,7 @@ export type Settings = {
finishedOnboarding?: boolean; // the user has completed the onboarding process finishedOnboarding?: boolean; // the user has completed the onboarding process
firstName?: string; // user's full name, may be null if unwanted for a particular account firstName?: string; // user's full name, may be null if unwanted for a particular account
hasBackedUpSeed?: boolean; // tracks whether the user has backed up their seed phrase
hideRegisterPromptOnNewContact?: boolean; hideRegisterPromptOnNewContact?: boolean;
isRegistered?: boolean; isRegistered?: boolean;
// imageServer?: string; // if we want to allow modification then we should make image functionality optional -- or at least customizable // imageServer?: string; // if we want to allow modification then we should make image functionality optional -- or at least customizable

17
src/views/SeedBackupView.vue

@ -231,9 +231,24 @@ export default class SeedBackupView extends Vue {
/** /**
* Reveals the seed phrase to the user * Reveals the seed phrase to the user
* Sets showSeed to true to display the sensitive seed phrase data * Sets showSeed to true to display the sensitive seed phrase data
* Updates the hasBackedUpSeed setting to true to track that user has backed up
*/ */
revealSeed(): void { async revealSeed(): Promise<void> {
this.showSeed = true; this.showSeed = true;
// Update the account setting to track that user has backed up their seed
try {
const settings = await this.$accountSettings();
if (settings.activeDid) {
await this.$saveUserSettings(settings.activeDid, {
hasBackedUpSeed: true,
});
}
} catch (err: unknown) {
logger.error("Failed to update hasBackedUpSeed setting:", err);
// Don't show error to user as this is not critical to the main functionality
// The seed phrase is still revealed, just the tracking won't work
}
} }
/** /**

Loading…
Cancel
Save