Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions apps/mobile/src/features/usage/UsageLimitsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,29 @@ function WindowRow(props: {
);
}

function AccountInstanceLabel({ value }: { readonly value: string }) {
const [revealed, setRevealed] = useState(false);
if (!value.includes("@")) {
return (
<Text className="shrink text-xs text-foreground-tertiary" numberOfLines={1}>
· {value}
</Text>
);
}
return (
<Pressable
className="shrink active:opacity-60"
accessibilityRole="button"
accessibilityLabel={revealed ? "Hide account label" : "Reveal account label"}
onPress={() => setRevealed((current) => !current)}
>
<Text className="text-xs text-foreground-tertiary" numberOfLines={1}>
· {revealed ? value : "••••••@••••••"}
</Text>
</Pressable>
);
}

/** One account: icon, name and plan on a single line, then its windows. */
export function AccountLimits(props: {
readonly driver: Driver;
Expand Down Expand Up @@ -128,9 +151,7 @@ export function AccountLimits(props: {
<View className="min-w-0 flex-1 flex-row items-baseline gap-2">
<Text className="text-base font-t3-medium text-foreground">{props.label}</Text>
{props.instanceLabel !== props.label ? (
<Text className="shrink text-xs text-foreground-tertiary" numberOfLines={1}>
· {props.instanceLabel}
</Text>
<AccountInstanceLabel key={props.instanceLabel} value={props.instanceLabel} />
) : null}
{props.detail ? (
<Text className="shrink text-sm text-foreground-muted" numberOfLines={1}>
Expand Down
32 changes: 28 additions & 4 deletions apps/web/src/components/chat/ComposerUsageLimits.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { limitsNotice } from "@t3tools/shared/usageLimits";
import { GaugeIcon } from "lucide-react";

import { getDriverOption } from "../settings/providerDriverMeta";
import { RedactedSensitiveText } from "../settings/RedactedSensitiveText";
import { LimitWindows, ResetCredits } from "../usage/UsageLimits";
import { ComposerBanner } from "./ComposerBanner";
import type { ComposerBannerStackItem } from "./ComposerBannerStack";
Expand All @@ -20,6 +21,27 @@ function accountLabel(account: UsageLimitsReport["accounts"][number]): string {
: driver;
}

function AccountSummary({ account }: { readonly account: UsageLimitsReport["accounts"][number] }) {
const label = accountLabel(account);
return (
<>
{label.includes("@") ? (
<RedactedSensitiveText
key={label}
value={label}
ariaLabel="Toggle account label visibility"
revealTooltip="Click to reveal account"
hideTooltip="Click to hide account"
className="max-w-full truncate align-bottom font-sans text-xs leading-normal"
/>
) : (
label
)}
{account.plan ? ` · ${account.plan}` : null}
</>
);
}

/** The /usage-limits result as a composer notice: it stacks under warnings and dismisses like one. */
export function usageLimitsBannerItem(
id: string,
Expand All @@ -29,9 +51,11 @@ export function usageLimitsBannerItem(
): ComposerBannerStackItem {
const [first] = report.accounts;
const single = report.accounts.length === 1 && first ? first : null;
const summary = single
? [accountLabel(single), single.plan].filter(Boolean).join(" · ")
: `${report.accounts.length} accounts`;
const summary = single ? (
<AccountSummary account={single} />
) : (
`${report.accounts.length} accounts`
);
return {
id,
variant: "info",
Expand Down Expand Up @@ -65,7 +89,7 @@ function UsageLimitsBannerBody({
<div key={account.id} className="flex min-w-0 flex-col gap-1">
{report.accounts.length > 1 ? (
<span className="truncate text-xs text-muted-foreground">
{[accountLabel(account), account.plan].filter(Boolean).join(" · ")}
<AccountSummary account={account} />
</span>
) : null}
{notice ? (
Expand Down
Loading