From ec2cab768bdd52e43c400349df3e3f5592e316d8 Mon Sep 17 00:00:00 2001 From: Jose Olarte III Date: Wed, 3 Sep 2025 15:52:29 +0800 Subject: [PATCH] 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. --- src/components/DataExportSection.vue | 30 +++++++++++++++++++++++++++- src/db-sql/migration.ts | 6 ++++++ src/db/tables/settings.ts | 1 + src/views/SeedBackupView.vue | 17 +++++++++++++++- 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/components/DataExportSection.vue b/src/components/DataExportSection.vue index 61bf4753..17524e79 100644 --- a/src/components/DataExportSection.vue +++ b/src/components/DataExportSection.vue @@ -16,6 +16,12 @@ messages * - Conditional UI based on platform capabilities * * @component * :to="{ name: 'seed-backup' }" :class="backupButtonClasses" > + + Backup Identifier Seed @@ -98,6 +104,12 @@ export default class DataExportSection extends Vue { */ 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 * 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) */ 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() { 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 { + 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; + } } } diff --git a/src/db-sql/migration.ts b/src/db-sql/migration.ts index 67944b75..0881dd02 100644 --- a/src/db-sql/migration.ts +++ b/src/db-sql/migration.ts @@ -124,6 +124,12 @@ const MIGRATIONS = [ 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; + `, + }, ]; /** diff --git a/src/db/tables/settings.ts b/src/db/tables/settings.ts index 0b86e355..ff43e0f8 100644 --- a/src/db/tables/settings.ts +++ b/src/db/tables/settings.ts @@ -29,6 +29,7 @@ export type Settings = { finishedOnboarding?: boolean; // the user has completed the onboarding process 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; isRegistered?: boolean; // imageServer?: string; // if we want to allow modification then we should make image functionality optional -- or at least customizable diff --git a/src/views/SeedBackupView.vue b/src/views/SeedBackupView.vue index c19caf13..fb9b7605 100644 --- a/src/views/SeedBackupView.vue +++ b/src/views/SeedBackupView.vue @@ -231,9 +231,24 @@ export default class SeedBackupView extends Vue { /** * Reveals the seed phrase to the user * 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 { 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 + } } /**