diff options
| author | Adam Malczewski <[email protected]> | 2026-10-14 17:29:03 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-10-14 17:29:03 +0900 |
| commit | 8853a2df4c8b255d8c6638858f525ed5a0387f5f (patch) | |
| tree | 68c71afe1ec59a58fd1fe2b30c486a31c33358f5 /src/app | |
| parent | d928bc86c35f590eb9113148bccf3c4ae56e8fa6 (diff) | |
| download | dispatch-web-8853a2df4c8b255d8c6638858f525ed5a0387f5f.tar.gz dispatch-web-8853a2df4c8b255d8c6638858f525ed5a0387f5f.zip | |
feat(account-usage): Hyper daily credits card with allowance + reset-time editor
Diffstat (limited to 'src/app')
| -rw-r--r-- | src/app/store.svelte.ts | 47 | ||||
| -rw-r--r-- | src/app/views/AccountUsagePane.svelte | 12 |
2 files changed, 54 insertions, 5 deletions
diff --git a/src/app/store.svelte.ts b/src/app/store.svelte.ts index 7433f81..0a9cbd1 100644 --- a/src/app/store.svelte.ts +++ b/src/app/store.svelte.ts @@ -56,8 +56,13 @@ import { subscribe as protocolSubscribe, unsubscribe as protocolUnsubscribe, } from "../core/protocol"; -import type { AccountUsageResult } from "../features/account-usage"; -import { normalizeAccountUsage } from "../features/account-usage"; +import type { + AccountUsageProviderId, + AccountUsageResult, + AccountUsageSettingsResult, + UpdateAccountUsageSettingsRequest, +} from "../features/account-usage"; +import { normalizeAccountUsage, normalizeAccountUsageReport } from "../features/account-usage"; import type { ChatStore, HistorySync, MetricsSync } from "../features/chat"; import { createChatStore, migrateLegacyModelName } from "../features/chat"; import type { SetThinkingRequest, ThinkingResponse } from "../features/chat/reasoning-effort"; @@ -544,6 +549,15 @@ export interface AppStore { */ accountUsage(opts?: { readonly refresh?: boolean }): Promise<AccountUsageResult>; /** + * Update a provider's usage settings (`PUT /usage/:provider/settings`; today + * only `hyper`: `dailyAllowance` + `resetAnchor` epoch-ms or null). Returns + * the provider's refreshed report. + */ + setAccountUsageSettings( + provider: AccountUsageProviderId, + settings: UpdateAccountUsageSettingsRequest, + ): Promise<AccountUsageSettingsResult>; + /** * Load the GLOBAL search-backend selection * (`GET /search/config`): which engine backs the `web_search` tool's search * mode. Not workspace-scoped — the selection is global. `unavailable: true` @@ -2613,6 +2627,35 @@ export function createAppStore(opts?: CreateAppStoreOptions): AppStore { } }, + async setAccountUsageSettings( + provider: AccountUsageProviderId, + settings: UpdateAccountUsageSettingsRequest, + ): Promise<AccountUsageSettingsResult> { + try { + const res = await fetchImpl(`${httpBase}/usage/${encodeURIComponent(provider)}/settings`, { + method: "PUT", + headers: { "content-type": "application/json" }, + body: JSON.stringify(settings), + }); + if (!res.ok) { + const errBody = (await res.json().catch(() => null)) as { error?: string } | null; + return { + ok: false, + error: errBody?.error ?? `Save usage settings failed (HTTP ${res.status})`, + }; + } + const report = normalizeAccountUsageReport(await res.json()); + return report + ? { ok: true, report } + : { ok: false, error: "Malformed usage settings response" }; + } catch (err) { + return { + ok: false, + error: err instanceof Error ? err.message : "Save usage settings request failed", + }; + } + }, + async concurrencyStatus(): Promise<ConcurrencyStatusResult> { try { const res = await fetchImpl(`${httpBase}/concurrency/status`); diff --git a/src/app/views/AccountUsagePane.svelte b/src/app/views/AccountUsagePane.svelte index 4315d4c..09afb5f 100644 --- a/src/app/views/AccountUsagePane.svelte +++ b/src/app/views/AccountUsagePane.svelte @@ -1,16 +1,22 @@ <script lang="ts"> /** - * The `account-usage` view — Claude + Codex subscription usage bars with + * The `account-usage` view — Claude + Codex + Hyper usage bars with * on-track pace markers. GLOBAL (not workspace/conversation scoped), so it * stays mounted across tab switches (no {#key}). */ - import { AccountUsageView, type LoadAccountUsage } from "../../features/account-usage"; + import { + AccountUsageView, + type LoadAccountUsage, + type SaveAccountUsageSettings, + } from "../../features/account-usage"; import type { AppViewPorts } from "../view-ports"; let { ports }: { ports: AppViewPorts } = $props(); const store = $derived(ports.store); const loadAccountUsage: LoadAccountUsage = (opts) => store.accountUsage(opts); + const saveAccountUsageSettings: SaveAccountUsageSettings = (provider, settings) => + store.setAccountUsageSettings(provider, settings); </script> -<AccountUsageView load={loadAccountUsage} /> +<AccountUsageView load={loadAccountUsage} saveSettings={saveAccountUsageSettings} /> |
