diff --git a/extension/src/setup/setup.ts b/extension/src/setup/setup.ts index df67d90..1cbd6d7 100644 --- a/extension/src/setup/setup.ts +++ b/extension/src/setup/setup.ts @@ -28,13 +28,16 @@ async function loadWasm(): Promise { // --- State --- interface WizardState { - step: number; + step: number; // now 0..5; was 1..5 + mode: 'new' | 'attach' | null; // null until Step 0 picks hostType: 'gitea' | 'github'; hostUrl: string; repoPath: string; apiToken: string; connectionTested: boolean; + vaultProbe: import('./probe').VaultProbe | null; carrierImageBytes: Uint8Array | null; + referenceImageBytesAttach: Uint8Array | null; passphrase: string; passphraseConfirm: string; // zxcvbn meter state — -1 means "not yet scored" (empty passphrase). @@ -43,7 +46,9 @@ interface WizardState { passphraseVisible: boolean; confirmVisible: boolean; referenceImageBytes: Uint8Array | null; + verifiedHandle: number | null; creating: boolean; + attaching: boolean; error: string | null; extensionDetected: boolean; configPushed: boolean; @@ -51,13 +56,16 @@ interface WizardState { } const state: WizardState = { - step: 1, + step: 0, + mode: null, hostType: 'gitea', hostUrl: '', repoPath: '', apiToken: '', connectionTested: false, + vaultProbe: null, carrierImageBytes: null, + referenceImageBytesAttach: null, passphrase: '', passphraseConfirm: '', passphraseScore: -1, @@ -65,7 +73,9 @@ const state: WizardState = { passphraseVisible: false, confirmVisible: false, referenceImageBytes: null, + verifiedHandle: null, creating: false, + attaching: false, error: null, extensionDetected: false, configPushed: false, @@ -224,6 +234,7 @@ function render(): void { const progressHtml = `
+
@@ -234,9 +245,10 @@ function render(): void { let stepHtml = ''; switch (state.step) { + case 0: stepHtml = renderStep0(); break; case 1: stepHtml = renderStep1(); break; case 2: stepHtml = renderStep2(); break; - case 3: stepHtml = renderStep3(); break; + case 3: stepHtml = state.mode === 'attach' ? renderStep3Attach() : renderStep3New(); break; case 4: stepHtml = renderStep4(); break; case 5: stepHtml = renderStep5(); break; } @@ -252,14 +264,43 @@ function render(): void { `; switch (state.step) { + case 0: attachStep0(); break; case 1: attachStep1(); break; case 2: attachStep2(); break; - case 3: attachStep3(); break; + case 3: state.mode === 'attach' ? attachStep3Attach() : attachStep3New(); break; case 4: attachStep4(); break; case 5: attachStep5(); break; } } +// --- Step 0: Mode picker (placeholder; filled in Task 5) --- + +function renderStep0(): string { + return '

Step 0 (placeholder)

'; +} + +function attachStep0(): void { + // Temporary: jump straight to Step 1 so the wizard remains operable + // for users who already have it open during the refactor. Real Step 0 + // is filled in by Task 5. + document.getElementById('next-btn')?.addEventListener('click', () => { + state.step = 1; + state.mode = 'new'; // safe default while picker is stubbed + state.error = null; + render(); + }); +} + +// --- Step 3 (attach variant) — placeholder; filled in Task 8 --- + +function renderStep3Attach(): string { + return '

Step 3b (placeholder)

'; +} + +function attachStep3Attach(): void { + /* filled in Task 8 */ +} + // --- Step 1: Choose Host --- function renderStep1(): string { @@ -398,9 +439,9 @@ function attachStep2(): void { }); } -// --- Step 3: Create Vault --- +// --- Step 3 (new-vault variant): Create Vault --- -function renderStep3(): string { +function renderStep3New(): string { const score = state.passphraseScore; const guessesLog10 = state.passphraseGuessesLog10; const hasScore = score >= 0; @@ -485,7 +526,7 @@ function renderStep3(): string { `; } -function attachStep3(): void { +function attachStep3New(): void { const fileDrop = document.getElementById('file-drop')!; const fileInput = document.getElementById('file-input') as HTMLInputElement;