|
61 | 61 | let hasLoadedSourceAddresses = $state(false); |
62 | 62 | let hasLoadedPrivateAddresses = $state(false); |
63 | 63 | let addressLoadingError = $state<string | null>(null); |
| 64 | + let showManualPrimaryInput = $state(false); |
64 | 65 |
|
65 | 66 | // Load addresses when component mounts |
66 | 67 | $effect(() => { |
|
71 | 72 |
|
72 | 73 | async function loadSourceAddresses() { |
73 | 74 | if (isLoadingSourceAddresses || hasLoadedSourceAddresses) return; |
74 | | - |
| 75 | +
|
75 | 76 | isLoadingSourceAddresses = true; |
76 | 77 | hasLoadedSourceAddresses = false; |
77 | | - |
| 78 | +
|
78 | 79 | try { |
79 | | - const allAddresses = []; |
80 | | - |
81 | | - // Get addresses by account (default account "") |
| 80 | + // Get addresses by account (default account "") - R-addresses only for primary addresses |
82 | 81 | try { |
83 | 82 | const addresses = await invoke('get_addresses_by_account', { account: "" }); |
84 | 83 | if (Array.isArray(addresses)) { |
85 | | - allAddresses.push(...addresses); |
86 | | - console.log('✅ Loaded addresses from default account:', addresses.length); |
| 84 | + sourceAddresses = addresses; |
| 85 | + console.log('✅ IdentityOfferForm: Loaded', addresses.length, 'R-addresses for primary addresses'); |
87 | 86 | } |
88 | 87 | } catch (err) { |
89 | 88 | console.error('Failed to load addresses by account:', err); |
| 89 | + addressLoadingError = `Failed to load R-addresses: ${err}`; |
90 | 90 | } |
91 | | - |
92 | | - // Also get private addresses from z_list_addresses |
93 | | - try { |
94 | | - const privateAddressList = await invoke('z_list_addresses'); |
95 | | - if (Array.isArray(privateAddressList)) { |
96 | | - allAddresses.push(...privateAddressList); |
97 | | - console.log('✅ Loaded private addresses:', privateAddressList.length); |
98 | | - } |
99 | | - } catch (err) { |
100 | | - console.error('Failed to load private addresses:', err); |
101 | | - } |
102 | | - |
103 | | - sourceAddresses = allAddresses; |
| 91 | +
|
104 | 92 | hasLoadedSourceAddresses = true; |
105 | | - console.log('✅ IdentityOfferForm: Loaded', allAddresses.length, 'source addresses'); |
106 | | - |
107 | | - // Do not auto-populate - let user explicitly select an address |
108 | | - |
| 93 | +
|
109 | 94 | } catch (err) { |
110 | 95 | console.error('Critical error in loadSourceAddresses:', err); |
111 | 96 | addressLoadingError = `Failed to load source addresses: ${err}`; |
|
162 | 147 | } |
163 | 148 | } |
164 | 149 |
|
| 150 | + function handlePrimaryAddressDropdownChange(event: Event) { |
| 151 | + const target = event.target as HTMLSelectElement; |
| 152 | + if (target.value === '__MANUAL__') { |
| 153 | + showManualPrimaryInput = true; |
| 154 | + localIdentityData.primaryAddresses[0] = ''; |
| 155 | + } else { |
| 156 | + showManualPrimaryInput = false; |
| 157 | + localIdentityData.primaryAddresses[0] = target.value; |
| 158 | + } |
| 159 | + } |
| 160 | +
|
| 161 | + function switchToDropdown() { |
| 162 | + showManualPrimaryInput = false; |
| 163 | + localIdentityData.primaryAddresses[0] = ''; |
| 164 | + } |
| 165 | +
|
165 | 166 | function notifyChange() { |
166 | 167 | // Pass camelCase for internal component communication (consistency with other forms) |
167 | 168 | // The conversion to lowercase for RPC happens in the parent component |
|
258 | 259 | {#each localIdentityData.primaryAddresses as _, index} |
259 | 260 | <div class="flex space-x-2 mb-2"> |
260 | 261 | {#if index === 0} |
261 | | - <!-- First address: dropdown from loaded addresses --> |
262 | | - <select |
263 | | - bind:value={localIdentityData.primaryAddresses[index]} |
264 | | - required |
265 | | - disabled={disabled || isLoadingSourceAddresses} |
266 | | - class="flex-1 p-3 border border-verusidx-mountain-mist dark:border-verusidx-stone-medium rounded-lg bg-white dark:bg-verusidx-stone-dark text-verusidx-stone-dark dark:text-white disabled:opacity-50" |
267 | | - > |
268 | | - <option value=""> |
269 | | - {#if isLoadingSourceAddresses} |
270 | | - Loading addresses... |
271 | | - {:else if hasLoadedSourceAddresses && sourceAddresses.length === 0} |
272 | | - No addresses available |
273 | | - {:else if !hasLoadedSourceAddresses} |
274 | | - Failed to load addresses |
275 | | - {:else} |
276 | | - Select address |
277 | | - {/if} |
278 | | - </option> |
279 | | - {#each sourceAddresses as addr} |
280 | | - <option value={addr}>{addr}{addr.startsWith('z') ? ' (Private)' : ' (Transparent)'}</option> |
281 | | - {/each} |
282 | | - </select> |
| 262 | + <!-- First address: dropdown or manual input --> |
| 263 | + {#if !showManualPrimaryInput} |
| 264 | + <select |
| 265 | + onchange={handlePrimaryAddressDropdownChange} |
| 266 | + value={localIdentityData.primaryAddresses[index]} |
| 267 | + required |
| 268 | + disabled={disabled || isLoadingSourceAddresses} |
| 269 | + class="flex-1 p-3 border border-verusidx-mountain-mist dark:border-verusidx-stone-medium rounded-lg bg-white dark:bg-verusidx-stone-dark text-verusidx-stone-dark dark:text-white disabled:opacity-50" |
| 270 | + > |
| 271 | + <option value=""> |
| 272 | + {#if isLoadingSourceAddresses} |
| 273 | + Loading addresses... |
| 274 | + {:else if hasLoadedSourceAddresses && sourceAddresses.length === 0} |
| 275 | + No addresses available |
| 276 | + {:else if !hasLoadedSourceAddresses} |
| 277 | + Failed to load addresses |
| 278 | + {:else} |
| 279 | + Select primary address... |
| 280 | + {/if} |
| 281 | + </option> |
| 282 | + <option value="__MANUAL__">Input address manually</option> |
| 283 | + {#each sourceAddresses as addr} |
| 284 | + <option value={addr}>{addr}</option> |
| 285 | + {/each} |
| 286 | + </select> |
| 287 | + {:else} |
| 288 | + <div class="flex-1"> |
| 289 | + <input |
| 290 | + type="text" |
| 291 | + bind:value={localIdentityData.primaryAddresses[index]} |
| 292 | + required |
| 293 | + placeholder="Enter primary address (R-address)" |
| 294 | + disabled={disabled} |
| 295 | + class="w-full p-3 border border-verusidx-mountain-mist dark:border-verusidx-stone-medium rounded-lg bg-white dark:bg-verusidx-stone-dark text-verusidx-stone-dark dark:text-white disabled:opacity-50" |
| 296 | + /> |
| 297 | + <button |
| 298 | + type="button" |
| 299 | + onclick={switchToDropdown} |
| 300 | + class="mt-1 text-xs text-verusidx-turquoise-deep hover:text-verusidx-turquoise-bright" |
| 301 | + > |
| 302 | + ← Use address dropdown |
| 303 | + </button> |
| 304 | + </div> |
| 305 | + {/if} |
283 | 306 | {:else} |
284 | 307 | <!-- Additional addresses: manual text input --> |
285 | | - <input |
| 308 | + <input |
286 | 309 | type="text" |
287 | 310 | bind:value={localIdentityData.primaryAddresses[index]} |
288 | 311 | required |
289 | 312 | disabled={disabled} |
290 | | - placeholder="Enter address manually" |
| 313 | + placeholder="Enter primary address (R-address)" |
291 | 314 | class="flex-1 p-3 border border-verusidx-mountain-mist dark:border-verusidx-stone-medium rounded-lg bg-white dark:bg-verusidx-stone-dark text-verusidx-stone-dark dark:text-white disabled:opacity-50" |
292 | 315 | /> |
293 | 316 | {/if} |
|
0 commit comments