@cortexkit/opencode-anthropic-auth 2.0.2 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -845
- package/dist/cli-failure.d.ts +38 -7
- package/dist/cli.js +50 -102
- package/dist/custody-mode.d.ts +1 -0
- package/dist/fable-fallback.d.ts +6 -2
- package/dist/index-0kxy8k2c.js +2 -0
- package/dist/index-1nwcnxp8.js +42 -0
- package/dist/index-53nnxq39.js +2 -0
- package/dist/{index-2arfb1y3.js → index-6chd6jnr.js} +1 -1
- package/dist/{index-1tbpt45x.js → index-ah5s0bew.js} +1 -1
- package/dist/index-b1dvkp15.js +2 -0
- package/dist/{index-mge0rw54.js → index-f2ne65w4.js} +1 -1
- package/dist/{index-rqync0pc.js → index-hazrk5c3.js} +1 -1
- package/dist/{index-1jkyhgyr.js → index-jexctf5w.js} +1 -1
- package/dist/index.js +1 -1
- package/dist/quota-preflight.d.ts +1 -0
- package/dist/request-class.d.ts +10 -0
- package/dist/rpc/port-file.js +1 -1
- package/dist/rpc/protocol.js +1 -1
- package/dist/rpc/rpc-client.js +1 -1
- package/dist/rpc/rpc-dir.js +1 -1
- package/dist/setup/command.d.ts +5 -14
- package/dist/setup/native-activation.d.ts +21 -8
- package/dist/setup/native-enrollment.d.ts +21 -0
- package/dist/setup/native-local.d.ts +31 -1
- package/dist/setup/native-login.d.ts +12 -1
- package/dist/setup/process-fence.d.ts +0 -6
- package/dist/setup/types.d.ts +9 -0
- package/dist/sidebar-state.d.ts +20 -2
- package/dist/sidebar-state.js +1 -1
- package/dist/transform.d.ts +2 -8
- package/dist/tui-preferences.js +1 -1
- package/dist/tui.d.ts +0 -2
- package/dist/v2/activation.d.ts +2 -0
- package/dist/v2/adapter.d.ts +11 -1
- package/dist/v2/cachekeep.d.ts +19 -0
- package/dist/v2/menu.d.ts +2 -1
- package/dist/v2/server.js +4 -4
- package/dist/v2/setup.d.ts +2 -0
- package/dist/v2/source.d.ts +1 -0
- package/dist/v2/tui.js +1 -1
- package/package.json +10 -6
- package/src/sidebar-state.ts +105 -30
- package/src/tui-compiled/sidebar-state.ts +105 -30
- package/src/tui-compiled/tui.tsx +395 -241
- package/src/tui.tsx +199 -58
- package/dist/index-227rsmfv.js +0 -42
- package/dist/index-74r84r5f.js +0 -1
- package/dist/index-b3mxpp4w.js +0 -2
- package/dist/index-fn0zqnnw.js +0 -3
- package/dist/index-j0wsgy54.js +0 -449
- package/dist/index-jc8p0tkv.js +0 -2
- package/dist/setup/activation.d.ts +0 -7
- package/dist/setup/command.test.d.ts +0 -1
- package/dist/setup/detect.d.ts +0 -8
- package/dist/setup/host-executable.d.ts +0 -3
- package/dist/setup/jsonc.d.ts +0 -9
- package/dist/setup/opencode-config.d.ts +0 -18
- package/dist/setup/pi.d.ts +0 -18
package/src/tui.tsx
CHANGED
|
@@ -3,16 +3,23 @@
|
|
|
3
3
|
import { readFileSync } from 'node:fs'
|
|
4
4
|
import { dirname, join } from 'node:path'
|
|
5
5
|
import { fileURLToPath } from 'node:url'
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
formatCreditAmounts,
|
|
8
|
+
type QuotaWindowPart,
|
|
9
|
+
quotaDisplayProjection,
|
|
10
|
+
quotaWindowParts,
|
|
11
|
+
} from '@cortexkit/anthropic-auth-core'
|
|
7
12
|
import type {
|
|
8
13
|
TuiPlugin,
|
|
9
14
|
TuiPluginApi,
|
|
10
15
|
TuiPluginModule,
|
|
11
16
|
} from '@opencode-ai/plugin/tui'
|
|
17
|
+
import { type BoxRenderable, TextAttributes } from '@opentui/core'
|
|
12
18
|
import {
|
|
13
19
|
createEffect,
|
|
14
20
|
createSignal,
|
|
15
21
|
For,
|
|
22
|
+
Index,
|
|
16
23
|
type JSX,
|
|
17
24
|
onCleanup,
|
|
18
25
|
Show,
|
|
@@ -25,7 +32,8 @@ import {
|
|
|
25
32
|
DEFAULT_SIDEBAR_STATE,
|
|
26
33
|
FIVE_HOUR_MS,
|
|
27
34
|
formatPrimeAccountValue,
|
|
28
|
-
|
|
35
|
+
formatQuotaRowLabel,
|
|
36
|
+
getCollapsedAccounts,
|
|
29
37
|
getCollapsedQuotaSummary,
|
|
30
38
|
getFableRecoverySummary,
|
|
31
39
|
getSidebarState,
|
|
@@ -232,7 +240,60 @@ function CollapsedRow(props: {
|
|
|
232
240
|
)
|
|
233
241
|
}
|
|
234
242
|
|
|
235
|
-
|
|
243
|
+
function CollapsedAccountRow(props: {
|
|
244
|
+
theme: ThemeCurrent
|
|
245
|
+
account: ReturnType<typeof getCollapsedAccounts>[number]
|
|
246
|
+
tone: Tone
|
|
247
|
+
}) {
|
|
248
|
+
const [width, setWidth] = createSignal(40)
|
|
249
|
+
let row: BoxRenderable | undefined
|
|
250
|
+
const summary = () => getCollapsedQuotaSummary(props.account.quota)
|
|
251
|
+
const value = () => summary().text ?? '—'
|
|
252
|
+
const labelWidth = () => Math.max(0, width() - Bun.stringWidth(value()) - 1)
|
|
253
|
+
const dim = () =>
|
|
254
|
+
!props.account.active || props.account.quotaDated || summary().stale
|
|
255
|
+
const attributes = () => (dim() ? TextAttributes.DIM : TextAttributes.BOLD)
|
|
256
|
+
const color = () =>
|
|
257
|
+
dim() ? props.theme.textMuted : toneColor(props.theme, props.tone)
|
|
258
|
+
return (
|
|
259
|
+
<box
|
|
260
|
+
width='100%'
|
|
261
|
+
height={1}
|
|
262
|
+
flexDirection='row'
|
|
263
|
+
ref={(element: BoxRenderable) => {
|
|
264
|
+
row = element
|
|
265
|
+
setWidth(element.width || 40)
|
|
266
|
+
}}
|
|
267
|
+
onSizeChange={() => setWidth(row?.width || 40)}
|
|
268
|
+
>
|
|
269
|
+
<Show when={labelWidth() > 0}>
|
|
270
|
+
<text
|
|
271
|
+
width={labelWidth()}
|
|
272
|
+
flexShrink={0}
|
|
273
|
+
wrapMode='none'
|
|
274
|
+
fg={color()}
|
|
275
|
+
attributes={attributes()}
|
|
276
|
+
>
|
|
277
|
+
{formatQuotaRowLabel(props.account.name, labelWidth())}
|
|
278
|
+
</text>
|
|
279
|
+
<text width={1} flexShrink={0}>
|
|
280
|
+
{' '}
|
|
281
|
+
</text>
|
|
282
|
+
</Show>
|
|
283
|
+
<text
|
|
284
|
+
width={Bun.stringWidth(value())}
|
|
285
|
+
flexShrink={0}
|
|
286
|
+
wrapMode='none'
|
|
287
|
+
fg={color()}
|
|
288
|
+
attributes={attributes()}
|
|
289
|
+
>
|
|
290
|
+
{value()}
|
|
291
|
+
</text>
|
|
292
|
+
</box>
|
|
293
|
+
)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Quota window row: muted label left, tone-colored bar + shared figure right,
|
|
236
297
|
// with an optional muted reset suffix. When pacing data is present, the bar
|
|
237
298
|
// gains a pace segment and an off-pace window adds a muted subline with the
|
|
238
299
|
// reserve/deficit delta and the projected runout.
|
|
@@ -240,12 +301,13 @@ function QuotaRow(props: {
|
|
|
240
301
|
theme: ThemeCurrent
|
|
241
302
|
appearance: AppearancePrefs
|
|
242
303
|
label: string
|
|
243
|
-
|
|
304
|
+
part: QuotaWindowPart | undefined
|
|
305
|
+
usedPercent: number | undefined
|
|
244
306
|
pacing: QuotaPacing | null
|
|
245
307
|
binding?: boolean
|
|
246
308
|
}) {
|
|
247
|
-
const used = () => props.
|
|
248
|
-
const reset = () =>
|
|
309
|
+
const used = () => props.usedPercent ?? 0
|
|
310
|
+
const reset = () => props.part?.resetIn
|
|
249
311
|
const paceLine = () => {
|
|
250
312
|
const pacing = props.pacing
|
|
251
313
|
if (!pacing || pacing.state === 'on-pace') return null
|
|
@@ -257,20 +319,24 @@ function QuotaRow(props: {
|
|
|
257
319
|
}
|
|
258
320
|
return (
|
|
259
321
|
<Show
|
|
260
|
-
when={props.
|
|
322
|
+
when={props.part}
|
|
261
323
|
fallback={
|
|
262
324
|
<box width='100%' flexDirection='row'>
|
|
263
|
-
<text
|
|
325
|
+
<text
|
|
326
|
+
fg={props.theme.textMuted}
|
|
327
|
+
>{`${formatQuotaRowLabel(props.label)} `}</text>
|
|
264
328
|
<text fg={props.theme.textMuted}>{'\u2014'}</text>
|
|
265
329
|
</box>
|
|
266
330
|
}
|
|
267
331
|
>
|
|
268
|
-
{/* Left group (label · bar ·
|
|
269
|
-
bars and
|
|
332
|
+
{/* Left group (label · bar · figure) stays left-aligned in fixed columns so
|
|
333
|
+
bars and figures line up across rows; the reset time is pushed to
|
|
270
334
|
the right edge so reset times align in their own right column. */}
|
|
271
335
|
<box width='100%' flexDirection='row' justifyContent='space-between'>
|
|
272
336
|
<box flexDirection='row'>
|
|
273
|
-
<text
|
|
337
|
+
<text
|
|
338
|
+
fg={props.theme.textMuted}
|
|
339
|
+
>{`${formatQuotaRowLabel(props.label)} `}</text>
|
|
274
340
|
<For each={quotaBarSegments(used(), props.appearance, props.pacing)}>
|
|
275
341
|
{(segment) => (
|
|
276
342
|
<text fg={toneColor(props.theme, segment.tone)}>
|
|
@@ -281,7 +347,7 @@ function QuotaRow(props: {
|
|
|
281
347
|
<text
|
|
282
348
|
fg={toneColor(props.theme, usageTone(used(), props.appearance))}
|
|
283
349
|
>
|
|
284
|
-
{` ${
|
|
350
|
+
{` ${props.part?.figure}${props.binding ? ' •' : ''}`}
|
|
285
351
|
</text>
|
|
286
352
|
</box>
|
|
287
353
|
<Show when={reset()}>
|
|
@@ -290,7 +356,7 @@ function QuotaRow(props: {
|
|
|
290
356
|
</box>
|
|
291
357
|
<Show when={paceLine()}>
|
|
292
358
|
<box width='100%' flexDirection='row'>
|
|
293
|
-
<text fg={props.theme.textMuted}>{'
|
|
359
|
+
<text fg={props.theme.textMuted}>{formatQuotaRowLabel('', 11)}</text>
|
|
294
360
|
<text
|
|
295
361
|
fg={toneColor(
|
|
296
362
|
props.theme,
|
|
@@ -305,6 +371,22 @@ function QuotaRow(props: {
|
|
|
305
371
|
)
|
|
306
372
|
}
|
|
307
373
|
|
|
374
|
+
// The shared credit figure followed by the spent and limit amounts:
|
|
375
|
+
// `credits 75% left · $25.00/$100.00`. When that line is wider than the
|
|
376
|
+
// measured width, the amounts drop their cents (`$1,250/$5,000`) instead of
|
|
377
|
+
// wrapping onto a second line.
|
|
378
|
+
function creditLine(
|
|
379
|
+
figure: string,
|
|
380
|
+
extraUsage: AccountQuota['extraUsage'],
|
|
381
|
+
width: number | undefined,
|
|
382
|
+
) {
|
|
383
|
+
const amounts = formatCreditAmounts(extraUsage)
|
|
384
|
+
if (!amounts) return figure
|
|
385
|
+
const line = `${figure} · ${amounts}`
|
|
386
|
+
if (width === undefined || Bun.stringWidth(line) <= width) return line
|
|
387
|
+
return `${figure} · ${formatCreditAmounts(extraUsage, { wholeUnits: true })}`
|
|
388
|
+
}
|
|
389
|
+
|
|
308
390
|
// Account block: header row (name + status word) then per-window quota rows.
|
|
309
391
|
// Pacing is computed here — per window, against the wall clock at render time
|
|
310
392
|
// (re-evaluated on every state poll) — and disabled by passing false.
|
|
@@ -317,19 +399,23 @@ function AccountBlock(props: {
|
|
|
317
399
|
pacingEnabled: boolean
|
|
318
400
|
needsReauth?: boolean
|
|
319
401
|
vaultReauth?: boolean
|
|
402
|
+
stateLine?: string
|
|
403
|
+
quotaDated?: boolean
|
|
320
404
|
tierLabel?: string
|
|
321
405
|
marginTop?: number
|
|
322
406
|
}) {
|
|
323
407
|
const statusWord = () =>
|
|
324
|
-
props.
|
|
325
|
-
? '
|
|
326
|
-
: props.
|
|
327
|
-
? '
|
|
328
|
-
: props.
|
|
329
|
-
? '
|
|
330
|
-
:
|
|
408
|
+
props.quotaDated && props.quota
|
|
409
|
+
? 'dated'
|
|
410
|
+
: props.needsReauth
|
|
411
|
+
? 're-login'
|
|
412
|
+
: props.vaultReauth
|
|
413
|
+
? 'needs sign-in in the vault'
|
|
414
|
+
: props.active
|
|
415
|
+
? 'active'
|
|
416
|
+
: 'idle'
|
|
331
417
|
const statusTone = (): Tone =>
|
|
332
|
-
props.needsReauth || props.vaultReauth
|
|
418
|
+
props.needsReauth || props.vaultReauth || props.stateLine
|
|
333
419
|
? 'warn'
|
|
334
420
|
: props.active
|
|
335
421
|
? 'ok'
|
|
@@ -340,9 +426,15 @@ function AccountBlock(props: {
|
|
|
340
426
|
| undefined,
|
|
341
427
|
windowMs: number,
|
|
342
428
|
) =>
|
|
343
|
-
props.pacingEnabled && window
|
|
429
|
+
props.pacingEnabled && !props.quotaDated && window
|
|
344
430
|
? computeQuotaPacing(window, windowMs, Date.now())
|
|
345
431
|
: null
|
|
432
|
+
const parts = () => {
|
|
433
|
+
const now = Date.now()
|
|
434
|
+
return quotaWindowParts(quotaDisplayProjection(props.quota, now), { now })
|
|
435
|
+
}
|
|
436
|
+
const partFor = (name: string) =>
|
|
437
|
+
parts().windows.find((part) => part.name === name)
|
|
346
438
|
return (
|
|
347
439
|
<box width='100%' flexDirection='column' marginTop={props.marginTop ?? 0}>
|
|
348
440
|
<box width='100%' flexDirection='row' justifyContent='space-between'>
|
|
@@ -353,6 +445,9 @@ function AccountBlock(props: {
|
|
|
353
445
|
<b>{statusWord()}</b>
|
|
354
446
|
</text>
|
|
355
447
|
</box>
|
|
448
|
+
<Show when={props.stateLine}>
|
|
449
|
+
<text fg={props.theme.textMuted}>{props.stateLine}</text>
|
|
450
|
+
</Show>
|
|
356
451
|
<Show
|
|
357
452
|
when={props.quota}
|
|
358
453
|
fallback={<text fg={props.theme.textMuted}>{'checking\u2026'}</text>}
|
|
@@ -361,7 +456,8 @@ function AccountBlock(props: {
|
|
|
361
456
|
theme={props.theme}
|
|
362
457
|
appearance={props.appearance}
|
|
363
458
|
label='5h'
|
|
364
|
-
|
|
459
|
+
part={partFor('5h')}
|
|
460
|
+
usedPercent={props.quota?.five_hour?.usedPercent}
|
|
365
461
|
pacing={pacingFor(props.quota?.five_hour, FIVE_HOUR_MS)}
|
|
366
462
|
binding={props.quota?.bindingWindow === 'five_hour'}
|
|
367
463
|
/>
|
|
@@ -369,7 +465,8 @@ function AccountBlock(props: {
|
|
|
369
465
|
theme={props.theme}
|
|
370
466
|
appearance={props.appearance}
|
|
371
467
|
label='7d'
|
|
372
|
-
|
|
468
|
+
part={partFor('7d')}
|
|
469
|
+
usedPercent={props.quota?.seven_day?.usedPercent}
|
|
373
470
|
pacing={pacingFor(props.quota?.seven_day, SEVEN_DAY_MS)}
|
|
374
471
|
binding={props.quota?.bindingWindow === 'seven_day'}
|
|
375
472
|
/>
|
|
@@ -378,29 +475,52 @@ function AccountBlock(props: {
|
|
|
378
475
|
<QuotaRow
|
|
379
476
|
theme={props.theme}
|
|
380
477
|
appearance={props.appearance}
|
|
381
|
-
label={
|
|
382
|
-
|
|
478
|
+
label={partFor(window.title)?.name ?? window.title}
|
|
479
|
+
part={partFor(window.title)}
|
|
480
|
+
usedPercent={window.usedPercent}
|
|
383
481
|
pacing={pacingFor(window, SEVEN_DAY_MS)}
|
|
384
482
|
binding={props.quota?.bindingWindow === window.id}
|
|
385
483
|
/>
|
|
386
484
|
)}
|
|
387
485
|
</For>
|
|
388
|
-
<Show when={
|
|
389
|
-
{(
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
486
|
+
<Show when={partFor('credits')}>
|
|
487
|
+
{(budget: () => QuotaWindowPart) => {
|
|
488
|
+
// The line box's laid-out width, read when it mounts and on each
|
|
489
|
+
// resize. It is undefined (amounts keep their cents) until layout.
|
|
490
|
+
const [width, setWidth] = createSignal<number>()
|
|
491
|
+
let line: BoxRenderable | undefined
|
|
492
|
+
return (
|
|
493
|
+
<box
|
|
494
|
+
width='100%'
|
|
495
|
+
ref={(element: BoxRenderable) => {
|
|
496
|
+
line = element
|
|
497
|
+
setWidth(element.width || undefined)
|
|
498
|
+
}}
|
|
499
|
+
onSizeChange={() => setWidth(line?.width || undefined)}
|
|
500
|
+
>
|
|
501
|
+
<text
|
|
502
|
+
fg={toneColor(
|
|
503
|
+
props.theme,
|
|
504
|
+
props.quota?.extraUsage?.severity === 'critical'
|
|
505
|
+
? 'err'
|
|
506
|
+
: props.quota?.extraUsage?.severity === 'warning' ||
|
|
507
|
+
props.quota?.extraUsage?.exhausted
|
|
508
|
+
? 'warn'
|
|
509
|
+
: 'muted',
|
|
510
|
+
)}
|
|
511
|
+
>
|
|
512
|
+
{creditLine(
|
|
513
|
+
budget().figure,
|
|
514
|
+
props.quota?.extraUsage,
|
|
515
|
+
width(),
|
|
516
|
+
)}
|
|
517
|
+
</text>
|
|
518
|
+
</box>
|
|
519
|
+
)
|
|
520
|
+
}}
|
|
521
|
+
</Show>
|
|
522
|
+
<Show when={parts().age}>
|
|
523
|
+
<text fg={props.theme.textMuted}>{parts().age}</text>
|
|
404
524
|
</Show>
|
|
405
525
|
<Show when={props.quota?.fallbackAdvised === true}>
|
|
406
526
|
<text fg={props.theme.textMuted}>{'→ fallback advised'}</text>
|
|
@@ -410,8 +530,6 @@ function AccountBlock(props: {
|
|
|
410
530
|
)
|
|
411
531
|
}
|
|
412
532
|
|
|
413
|
-
export { formatQuotaMoney }
|
|
414
|
-
|
|
415
533
|
// --- Quota dialog content ---------------------------------------------------
|
|
416
534
|
|
|
417
535
|
// Renders the same rich visualization as the sidebar (account blocks with
|
|
@@ -437,7 +555,9 @@ function QuotaDialogContent(props: {
|
|
|
437
555
|
setTimeout(refresh, 0)
|
|
438
556
|
const theme = () => props.api.theme.current
|
|
439
557
|
const enabledFallbacks = () =>
|
|
440
|
-
(state().fallbacks ?? []).filter(
|
|
558
|
+
(state().fallbacks ?? []).filter(
|
|
559
|
+
(f) => f.enabled || (f.custodyState && f.custodyState !== 'off'),
|
|
560
|
+
)
|
|
441
561
|
return (
|
|
442
562
|
<box flexDirection='column' padding={2} width='100%' alignItems='center'>
|
|
443
563
|
<box flexDirection='column' width={58}>
|
|
@@ -454,6 +574,8 @@ function QuotaDialogContent(props: {
|
|
|
454
574
|
active={state().activeId === 'main'}
|
|
455
575
|
pacingEnabled={prefs().sections.pacing}
|
|
456
576
|
tierLabel={state().main?.tierLabel}
|
|
577
|
+
stateLine={state().main?.stateLine}
|
|
578
|
+
quotaDated={state().main?.quotaDated}
|
|
457
579
|
/>
|
|
458
580
|
<Show when={prefs().sections.fallbackAccounts}>
|
|
459
581
|
<For each={enabledFallbacks()}>
|
|
@@ -467,6 +589,9 @@ function QuotaDialogContent(props: {
|
|
|
467
589
|
pacingEnabled={prefs().sections.pacing}
|
|
468
590
|
tierLabel={fb.tierLabel}
|
|
469
591
|
needsReauth={fb.needsReauth}
|
|
592
|
+
vaultReauth={fb.vaultReauth}
|
|
593
|
+
stateLine={fb.stateLine}
|
|
594
|
+
quotaDated={fb.quotaDated}
|
|
470
595
|
marginTop={1}
|
|
471
596
|
/>
|
|
472
597
|
)}
|
|
@@ -594,9 +719,13 @@ function QuotaSidebar(props: {
|
|
|
594
719
|
|
|
595
720
|
const theme = () => props.api.theme.current
|
|
596
721
|
const enabledFallbacks = () =>
|
|
597
|
-
(state().fallbacks ?? []).filter(
|
|
722
|
+
(state().fallbacks ?? []).filter(
|
|
723
|
+
(f) => f.enabled || (f.custodyState && f.custodyState !== 'off'),
|
|
724
|
+
)
|
|
598
725
|
const hasData = () =>
|
|
599
|
-
state().main?.quota != null ||
|
|
726
|
+
state().main?.quota != null ||
|
|
727
|
+
state().main?.stateLine != null ||
|
|
728
|
+
enabledFallbacks().length > 0
|
|
600
729
|
|
|
601
730
|
const headerLabel = () => {
|
|
602
731
|
const name = prefs().header.label
|
|
@@ -607,6 +736,7 @@ function QuotaSidebar(props: {
|
|
|
607
736
|
getCollapsedQuotaSummary(activeAccount().quota)
|
|
608
737
|
const activePacingDeficit = () => {
|
|
609
738
|
if (!prefs().sections.pacing) return false
|
|
739
|
+
if (activeAccount().quotaDated) return null
|
|
610
740
|
const quota = activeAccount().quota
|
|
611
741
|
if (!quota) return false
|
|
612
742
|
const now = Date.now()
|
|
@@ -724,18 +854,25 @@ function QuotaSidebar(props: {
|
|
|
724
854
|
</Show>
|
|
725
855
|
</box>
|
|
726
856
|
|
|
727
|
-
{/* Collapsed
|
|
857
|
+
{/* Collapsed accounts keep placement order; only a fresh active row is emphasized. */}
|
|
728
858
|
<Show when={collapsed() && hasData()}>
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
859
|
+
{/* Index keys rows by position: each state update builds new account
|
|
860
|
+
objects, so For would rebuild every row and its measured width.
|
|
861
|
+
Passing the accessor's value as a prop keeps the row reactive. */}
|
|
862
|
+
<Index
|
|
863
|
+
each={getCollapsedAccounts(
|
|
864
|
+
state(),
|
|
865
|
+
prefs().sections.fallbackAccounts,
|
|
866
|
+
)}
|
|
867
|
+
>
|
|
868
|
+
{(account) => (
|
|
869
|
+
<CollapsedAccountRow
|
|
870
|
+
theme={theme()}
|
|
871
|
+
account={account()}
|
|
872
|
+
tone={activeQuotaTone()}
|
|
873
|
+
/>
|
|
874
|
+
)}
|
|
875
|
+
</Index>
|
|
739
876
|
<Show when={state().fastMode}>
|
|
740
877
|
<CollapsedRow theme={theme()} label='Mode'>
|
|
741
878
|
<text fg={toneColor(theme(), 'accent')}>
|
|
@@ -776,6 +913,8 @@ function QuotaSidebar(props: {
|
|
|
776
913
|
active={state().activeId === 'main'}
|
|
777
914
|
pacingEnabled={prefs().sections.pacing}
|
|
778
915
|
tierLabel={state().main?.tierLabel}
|
|
916
|
+
stateLine={state().main?.stateLine}
|
|
917
|
+
quotaDated={state().main?.quotaDated}
|
|
779
918
|
/>
|
|
780
919
|
<Show when={prefs().sections.fallbackAccounts}>
|
|
781
920
|
<For each={enabledFallbacks()}>
|
|
@@ -790,6 +929,8 @@ function QuotaSidebar(props: {
|
|
|
790
929
|
tierLabel={fb.tierLabel}
|
|
791
930
|
needsReauth={fb.needsReauth}
|
|
792
931
|
vaultReauth={fb.vaultReauth}
|
|
932
|
+
stateLine={fb.stateLine}
|
|
933
|
+
quotaDated={fb.quotaDated}
|
|
793
934
|
marginTop={1}
|
|
794
935
|
/>
|
|
795
936
|
)}
|