feat(app): improve image picker, markdown rendering, and UI interactions

This commit is contained in:
Mohamed Boudra
2026-03-12 23:29:26 +07:00
parent 4b5cb5a3e2
commit 9190d86148
16 changed files with 642 additions and 91 deletions
@@ -156,8 +156,6 @@ export function WorkspaceDesktopTabsRow({
const layoutItem = layout.items[index] ?? null;
const resolvedTabWidth = layoutItem?.width ?? 150;
const showLabel = layoutItem?.showLabel ?? true;
const labelCharCap = layoutItem?.labelCharCap ?? tab.label.length;
const renderedLabel = showLabel ? tab.label.slice(0, Math.max(1, labelCharCap)) : "";
const presentation = deriveWorkspaceTabPresentation({ tab, agent: tabAgent });
const tooltipLabel =
tab.kind === "agent" && tab.titleState === "loading"
@@ -172,11 +170,7 @@ export function WorkspaceDesktopTabsRow({
return (
<ContextMenu key={tab.key}>
<Tooltip delayDuration={400} enabledOnDesktop enabledOnMobile={false}>
<TooltipTrigger
testID={`workspace-tab-tooltip-${tab.key}`}
accessibilityRole="none"
style={styles.tabTooltipTrigger}
>
<TooltipTrigger asChild triggerRefProp="triggerRef">
<ContextMenuTrigger
testID={`workspace-tab-${tab.key}`}
enabledOnMobile={false}
@@ -228,9 +222,11 @@ export function WorkspaceDesktopTabsRow({
isActive && styles.tabLabelActive,
shouldShowCloseButton && styles.tabLabelWithCloseButton,
]}
selectable={false}
numberOfLines={1}
ellipsizeMode="tail"
>
{renderedLabel}
{tab.label}
</Text>
)
) : null}
@@ -411,9 +407,6 @@ const styles = StyleSheet.create((theme) => ({
paddingRight: theme.spacing[2],
paddingVertical: theme.spacing[1],
},
tabTooltipTrigger: {
flexShrink: 0,
},
tab: {
paddingHorizontal: theme.spacing[3],
paddingVertical: theme.spacing[2],
@@ -421,6 +414,7 @@ const styles = StyleSheet.create((theme) => ({
flexDirection: "row",
alignItems: "center",
gap: theme.spacing[1],
userSelect: "none",
},
tabHandle: {
flexDirection: "row",
@@ -428,6 +422,7 @@ const styles = StyleSheet.create((theme) => ({
gap: theme.spacing[1],
flex: 1,
minWidth: 0,
userSelect: "none",
},
tabIcon: {
flexShrink: 0,
@@ -444,6 +439,7 @@ const styles = StyleSheet.create((theme) => ({
color: theme.colors.foregroundMuted,
fontSize: theme.fontSize.sm,
fontWeight: theme.fontWeight.normal,
userSelect: "none",
},
tabLabelSkeleton: {
width: 96,
@@ -344,6 +344,10 @@ function WorkspaceScreenContent({
const isWorkspaceHeaderLoading = workspaceHeader === null;
const isGitCheckout = checkoutQuery.data?.isGit ?? false;
const currentBranchName =
checkoutQuery.data?.isGit && checkoutQuery.data.currentBranch !== "HEAD"
? trimNonEmpty(checkoutQuery.data.currentBranch)
: null;
const mobileView = usePanelStore((state) => state.mobileView);
const desktopFileExplorerOpen = usePanelStore(
(state) => state.desktop.fileExplorerOpen
@@ -1025,6 +1029,20 @@ function WorkspaceScreenContent({
}
}, [normalizedWorkspaceId, toast]);
const handleCopyBranchName = useCallback(async () => {
if (!currentBranchName) {
toast.error("Branch name not available");
return;
}
try {
await Clipboard.setStringAsync(currentBranchName);
toast.copied("Branch name");
} catch {
toast.error("Copy failed");
}
}, [currentBranchName, toast]);
const handleBulkCloseTabs = useCallback(
async (input: { tabsToClose: WorkspaceTabDescriptor[]; title: string; logLabel: string }) => {
const { tabsToClose, title, logLabel } = input;
@@ -1389,6 +1407,20 @@ function WorkspaceScreenContent({
>
Copy workspace path
</DropdownMenuItem>
{currentBranchName ? (
<DropdownMenuItem
testID="workspace-header-copy-branch-name"
leading={
<Copy
size={16}
color={theme.colors.foregroundMuted}
/>
}
onSelect={handleCopyBranchName}
>
Copy branch name
</DropdownMenuItem>
) : null}
</DropdownMenuContent>
</DropdownMenu>
</View>