refactor(ext/setup): wizard state shape for mode-aware flow
Expand WizardState with mode/vaultProbe/referenceImageBytesAttach/ verifiedHandle/attaching fields; start wizard at step 0; grow progress bar to 6 segments; rename renderStep3/attachStep3 to *New variants; add placeholder renderStep0/attachStep0/renderStep3Attach/attachStep3Attach. No behaviour change for the existing new-vault flow. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -28,13 +28,16 @@ async function loadWasm(): Promise<WasmModule> {
|
||||
// --- 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 = `
|
||||
<div class="progress-bar">
|
||||
<div class="step ${state.step > 0 ? 'done' : state.step === 0 ? 'current' : ''}"></div>
|
||||
<div class="step ${state.step > 1 ? 'done' : state.step === 1 ? 'current' : ''}"></div>
|
||||
<div class="step ${state.step > 2 ? 'done' : state.step === 2 ? 'current' : ''}"></div>
|
||||
<div class="step ${state.step > 3 ? 'done' : state.step === 3 ? 'current' : ''}"></div>
|
||||
@@ -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 '<div class="wizard-step"><p>Step 0 (placeholder)</p><button class="btn btn-primary" id="next-btn">next</button></div>';
|
||||
}
|
||||
|
||||
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 '<div class="wizard-step"><p>Step 3b (placeholder)</p></div>';
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user