Show context usage beside compact mode selector

This commit is contained in:
Mohamed Boudra
2026-05-31 22:38:46 +07:00
parent 360110accc
commit 2227540fad
2 changed files with 62 additions and 35 deletions
+19 -21
View File
@@ -190,6 +190,7 @@ function renderContextWindowMeter(
contextWindowMaxTokens: number | null,
contextWindowUsedTokens: number | null,
totalCostUsd: number | null,
showPercentage: boolean,
): ReactElement | null {
if (contextWindowMaxTokens === null || contextWindowUsedTokens === null) {
return null;
@@ -199,6 +200,7 @@ function renderContextWindowMeter(
maxTokens={contextWindowMaxTokens}
usedTokens={contextWindowUsedTokens}
totalCostUsd={totalCostUsd}
showPercentage={showPercentage}
/>
);
}
@@ -206,13 +208,13 @@ function renderContextWindowMeter(
function resolveContextWindowPlacement(
meter: ReactElement | null,
isMobile: boolean,
): { beforeVoiceContent: ReactNode; footerRight: ReactNode } {
): { beforeVoiceContent: ReactNode; footerInlineContent: ReactNode } {
if (isMobile) {
return { beforeVoiceContent: null, footerRight: meter };
return { beforeVoiceContent: null, footerInlineContent: meter };
}
return {
beforeVoiceContent: <View style={styles.contextWindowMeterSlot}>{meter}</View>,
footerRight: null,
footerInlineContent: null,
};
}
@@ -238,13 +240,18 @@ interface RenderAttachmentTrayArgs {
handleRemoveAttachment: (index: number) => void;
}
function renderComposerFooter(footer: ReactNode, footerRight: ReactNode): ReactElement | null {
if (!footer && !footerRight) return null;
function renderComposerFooter(
footer: ReactNode,
footerInlineContent: ReactNode,
): ReactElement | null {
if (!footer && !footerInlineContent) return null;
return (
<View style={styles.footer}>
<View style={styles.footerContent}>
<View style={styles.footerLeft}>{footer}</View>
<View style={styles.footerRight}>{footerRight}</View>
<View style={styles.footerLeft}>
{footer}
{footerInlineContent}
</View>
</View>
</View>
);
@@ -1468,10 +1475,11 @@ export function Composer({
contextWindowMaxTokens,
contextWindowUsedTokens,
agentState.totalCostUsd,
isMobile,
),
[contextWindowMaxTokens, contextWindowUsedTokens, agentState.totalCostUsd],
[contextWindowMaxTokens, contextWindowUsedTokens, agentState.totalCostUsd, isMobile],
);
const { beforeVoiceContent, footerRight } = useMemo(
const { beforeVoiceContent, footerInlineContent } = useMemo(
() => resolveContextWindowPlacement(contextWindowMeter, isMobile),
[contextWindowMeter, isMobile],
);
@@ -1718,7 +1726,7 @@ export function Composer({
</View>
</View>
</View>
{renderComposerFooter(footer, footerRight)}
{renderComposerFooter(footer, footerInlineContent)}
</Animated.View>
);
}
@@ -1782,6 +1790,7 @@ const styles = StyleSheet.create((theme: Theme) => ({
flexShrink: 1,
flexDirection: "row",
alignItems: "center",
gap: theme.spacing[1],
// On mobile, cancel the leading glyph's internal padding (chip paddingHorizontal)
// so its icon aligns to the composer border before the footer inset is applied.
marginLeft: {
@@ -1789,17 +1798,6 @@ const styles = StyleSheet.create((theme: Theme) => ({
md: 0,
},
},
footerRight: {
flexShrink: 0,
flexDirection: "row",
alignItems: "center",
// On mobile, cancel the trailing glyph's internal inset (28px box around a 16px
// ring) so its right edge aligns to the composer border before the footer inset.
marginRight: {
xs: -6,
md: 0,
},
},
messageInputContainer: {
position: "relative",
width: "100%",