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
18 changes: 18 additions & 0 deletions apps/mobile/src/components/agents/chat-toolbar.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,24 @@ describe('ChatToolbar', () => {
expect(props.disabled).toBe(false);
});

it('keeps mode, model, and paste on one row', () => {
const onPaste = vi.fn(() => undefined);
// eslint-disable-next-line new-cap -- plain function call, matching repo test convention
const element = ChatToolbar({ ...defaultProps(), onPaste }) as Node;

const className =
element !== null &&
typeof element === 'object' &&
typeof element.props?.className === 'string'
? element.props.className
: '';
expect(className).toContain('flex-row');
expect(className).not.toContain('flex-wrap');

const pasteButtonProps = findElementByType(element, 'ComposerPasteButton') ?? {};
expect(pasteButtonProps.className).toContain('shrink-0');
});

it('locks only the model picker when modelLocked is true', () => {
// eslint-disable-next-line new-cap -- plain function call, matching repo test convention
const element = ChatToolbar({
Expand Down
8 changes: 2 additions & 6 deletions apps/mobile/src/components/agents/chat-toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,7 @@ export function ChatToolbar({

return (
<View
className={cn(
'flex-row flex-wrap items-center gap-2 px-3 py-2.5',
disabled && 'opacity-50',
className
)}
className={cn('flex-row items-center gap-2 px-3 py-2.5', disabled && 'opacity-50', className)}
>
{order === 'model-first' ? modelSelector : modeSelector}
{order === 'model-first' ? modeSelector : modelSelector}
Expand All @@ -86,7 +82,7 @@ export function ChatToolbar({
size="sm"
onPress={onPaste}
disabled={pasteDisabled}
className="ml-auto"
className="ml-auto shrink-0"
/>
) : null}
</View>
Expand Down
6 changes: 4 additions & 2 deletions apps/mobile/src/components/agents/mode-selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,14 @@ export function ModeSelector({
accessibilityLabel={t('agentChat.modeSelector.accessibility', { label: selectedLabel })}
accessibilityState={{ disabled }}
className={cn(
'flex-row items-center gap-1.5 rounded-full bg-secondary px-3 py-1.5 active:opacity-70',
'shrink-0 flex-row items-center gap-1.5 rounded-full bg-secondary px-3 py-1.5 active:opacity-70',
disabled && 'opacity-50'
)}
>
<ModeIcon size={14} color={colors.foreground} />
<Text className="text-sm font-medium text-foreground">{selectedLabel}</Text>
<Text className="text-sm font-medium text-foreground" numberOfLines={1}>
{selectedLabel}
</Text>
<ChevronDown size={14} color={colors.mutedForeground} />
</Pressable>
);
Expand Down
17 changes: 3 additions & 14 deletions apps/mobile/src/components/agents/model-selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,6 @@ function toSessionModelOption(option: ModelOption | SessionModelOption): Session
return { ...option, displayId: option.id, showGatewayMetadata: true };
}

function compactThinkingEffortLabel(variant: string) {
if (variant === 'xhigh') {
return i18n.t('agentChat.modelSelector.thinkingEffortXhigh');
}
if (variant === 'medium') {
return i18n.t('agentChat.modelSelector.thinkingEffortMedium');
}
return thinkingEffortLabel(variant);
}

export function openModelPicker(
router: ImperativeRouter,
params: {
Expand Down Expand Up @@ -146,7 +136,6 @@ export function ModelSelector({
const { byok, collectsData } = modelSelectorBadges(selectedModel);
const hasVariants = selectedModel ? selectedModel.variants.length > 1 : false;
const variantLabel = variant ? thinkingEffortLabel(variant) : '';
const compactVariantLabel = variant ? compactThinkingEffortLabel(variant) : '';
const dataLabel = collectsData ? getFreeModelDataAccessibilityLabel(label) : label;
const modelLabel = byok ? `${dataLabel}, ${BYOK_MODEL_LABEL}` : dataLabel;
const accessibilityLabel =
Expand All @@ -159,7 +148,7 @@ export function ModelSelector({
(lockLabel && disabled ? t('agentChat.modelSelector.lockedByAgent', { agent: lockLabel }) : '');
// A pinned variant is meaningful even when the locked option carries a single
// variant, so surface the badge whenever a lock label is present.
const showVariantBadge = compactVariantLabel !== '' && (hasVariants || Boolean(lockLabel));
const showVariantBadge = variantLabel !== '' && (hasVariants || Boolean(lockLabel));

function handlePress() {
if (effectivelyDisabled) {
Expand All @@ -182,7 +171,7 @@ export function ModelSelector({
accessibilityLabel={accessibilityLabel}
accessibilityState={{ disabled: effectivelyDisabled }}
className={cn(
'max-w-[240px] shrink flex-row items-center gap-1.5 rounded-full bg-secondary px-3 py-1.5 active:opacity-70',
'max-w-[240px] min-w-0 shrink flex-row items-center gap-1.5 rounded-full bg-secondary px-3 py-1.5 active:opacity-70',
effectivelyDisabled && 'opacity-50'
)}
>
Expand All @@ -205,7 +194,7 @@ export function ModelSelector({
<View className="flex-row items-center gap-1 rounded-full bg-neutral-200 px-1.5 py-0.5 dark:bg-neutral-800">
<Brain size={12} color={colors.mutedForeground} />
<Text className="text-xs font-medium text-muted-foreground" numberOfLines={1}>
{compactVariantLabel}
{variantLabel}
</Text>
</View>
) : null}
Expand Down
2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/af.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/am.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/ar.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/az.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/be.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/bg.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/bn.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/bs.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/ca.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/ckb.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/cs.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/cy.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/da.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/de.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/el.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2343,8 +2343,6 @@
"lockedByAgent": ", Locked by agent \"{{agent}}\"",
"addToFavorites": "Add {{name}} to favorites",
"removeFromFavorites": "Remove {{name}} from favorites",
"thinkingEffortXhigh": "XH",
"thinkingEffortMedium": "Med",
"sessionModel": "Session model"
},
"attachmentPreview": {
Expand Down
2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/es.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/et.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/eu.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/fa.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/fi.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/fil.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/fr.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/ga.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/gl.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/gu.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/ha.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/he.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/hi.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/hr.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions apps/mobile/src/i18n/locales/ht.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading