Add chord keyboard shortcuts and staged capture UI
This commit is contained in:
@@ -594,12 +594,14 @@ export function AgentInputArea({
|
||||
)}
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="top" align="center" offset={8}>
|
||||
<View style={styles.tooltipRow}>
|
||||
<Text style={styles.tooltipText}>Interrupt</Text>
|
||||
{dictationCancelKeys ? <Shortcut keys={dictationCancelKeys} style={styles.tooltipShortcut} /> : null}
|
||||
</View>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
<View style={styles.tooltipRow}>
|
||||
<Text style={styles.tooltipText}>Interrupt</Text>
|
||||
{dictationCancelKeys ? (
|
||||
<Shortcut chord={dictationCancelKeys} style={styles.tooltipShortcut} />
|
||||
) : null}
|
||||
</View>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
) : null;
|
||||
|
||||
const rightContent = (
|
||||
@@ -626,7 +628,9 @@ export function AgentInputArea({
|
||||
<TooltipContent side="top" align="center" offset={8}>
|
||||
<View style={styles.tooltipRow}>
|
||||
<Text style={styles.tooltipText}>Voice mode</Text>
|
||||
{voiceToggleKeys && <Shortcut keys={voiceToggleKeys} style={styles.tooltipShortcut} />}
|
||||
{voiceToggleKeys ? (
|
||||
<Shortcut chord={voiceToggleKeys} style={styles.tooltipShortcut} />
|
||||
) : null}
|
||||
</View>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
@@ -178,7 +178,7 @@ export function CommandCenter() {
|
||||
</View>
|
||||
</View>
|
||||
{action.shortcutKeys ? (
|
||||
<Shortcut keys={action.shortcutKeys} style={styles.rowShortcut} />
|
||||
<Shortcut chord={action.shortcutKeys} style={styles.rowShortcut} />
|
||||
) : null}
|
||||
</View>
|
||||
</CommandCenterRow>
|
||||
|
||||
@@ -565,7 +565,7 @@ function MobileSidebar({
|
||||
<TooltipContent side="top" align="center" offset={8}>
|
||||
<View style={styles.tooltipRow}>
|
||||
<Text style={styles.tooltipText}>Add project</Text>
|
||||
{newAgentKeys && <Shortcut keys={newAgentKeys} />}
|
||||
{newAgentKeys ? <Shortcut chord={newAgentKeys} /> : null}
|
||||
</View>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
@@ -745,7 +745,7 @@ function DesktopSidebar({
|
||||
<TooltipContent side="top" align="center" offset={8}>
|
||||
<View style={styles.tooltipRow}>
|
||||
<Text style={styles.tooltipText}>Add project</Text>
|
||||
{newAgentKeys ? <Shortcut keys={newAgentKeys} /> : null}
|
||||
{newAgentKeys ? <Shortcut chord={newAgentKeys} /> : null}
|
||||
</View>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
@@ -1013,7 +1013,11 @@ export const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(funct
|
||||
</Text>
|
||||
{(isRealtimeVoiceForCurrentAgent ? voiceMuteToggleKeys : dictationToggleKeys) ? (
|
||||
<Shortcut
|
||||
keys={(isRealtimeVoiceForCurrentAgent ? voiceMuteToggleKeys : dictationToggleKeys)!}
|
||||
chord={
|
||||
(isRealtimeVoiceForCurrentAgent
|
||||
? voiceMuteToggleKeys
|
||||
: dictationToggleKeys)!
|
||||
}
|
||||
style={styles.tooltipShortcut}
|
||||
/>
|
||||
) : null}
|
||||
@@ -1039,7 +1043,9 @@ export const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(funct
|
||||
<TooltipContent side="top" align="center" offset={8}>
|
||||
<View style={styles.tooltipRow}>
|
||||
<Text style={styles.tooltipText}>Queue</Text>
|
||||
{queueKeys ? <Shortcut keys={queueKeys} style={styles.tooltipShortcut} /> : null}
|
||||
{queueKeys ? (
|
||||
<Shortcut chord={queueKeys} style={styles.tooltipShortcut} />
|
||||
) : null}
|
||||
</View>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
@@ -1062,7 +1068,7 @@ export const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(funct
|
||||
<TooltipContent side="top" align="center" offset={8}>
|
||||
<View style={styles.tooltipRow}>
|
||||
<Text style={styles.tooltipText}>Send</Text>
|
||||
{sendKeys ? <Shortcut keys={sendKeys} style={styles.tooltipShortcut} /> : null}
|
||||
{sendKeys ? <Shortcut chord={sendKeys} style={styles.tooltipShortcut} /> : null}
|
||||
</View>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
@@ -150,7 +150,7 @@ interface WorkspaceRowInnerProps {
|
||||
onArchive?: () => void;
|
||||
onCopyBranchName?: () => void;
|
||||
onCopyPath?: () => void;
|
||||
archiveShortcutKeys?: ShortcutKey[] | null;
|
||||
archiveShortcutKeys?: ShortcutKey[][] | null;
|
||||
}
|
||||
|
||||
function resolveStatusDotColor(input: {
|
||||
@@ -322,7 +322,7 @@ function NewWorktreeButton({
|
||||
<View style={styles.projectActionTooltipRow}>
|
||||
<Text style={styles.projectActionTooltipText}>New worktree</Text>
|
||||
{showShortcutHint && newWorktreeKeys ? (
|
||||
<Shortcut keys={newWorktreeKeys} style={styles.projectActionTooltipShortcut} />
|
||||
<Shortcut chord={newWorktreeKeys} style={styles.projectActionTooltipShortcut} />
|
||||
) : null}
|
||||
</View>
|
||||
</TooltipContent>
|
||||
@@ -842,7 +842,7 @@ function WorkspaceRowInner({
|
||||
<DropdownMenuItem
|
||||
testID={`sidebar-workspace-menu-archive-${workspace.workspaceKey}`}
|
||||
leading={<Archive size={14} color={theme.colors.foregroundMuted} />}
|
||||
trailing={archiveShortcutKeys ? <Shortcut keys={archiveShortcutKeys} /> : null}
|
||||
trailing={archiveShortcutKeys ? <Shortcut chord={archiveShortcutKeys} /> : null}
|
||||
status={archiveStatus}
|
||||
pendingLabel={archivePendingLabel}
|
||||
onSelect={onArchive}
|
||||
|
||||
@@ -6,22 +6,49 @@ import { getShortcutOs } from "@/utils/shortcut-platform";
|
||||
|
||||
export function Shortcut({
|
||||
keys,
|
||||
chord,
|
||||
style,
|
||||
textStyle,
|
||||
}: {
|
||||
keys: ShortcutKey[];
|
||||
keys?: ShortcutKey[];
|
||||
chord?: ShortcutKey[][];
|
||||
style?: StyleProp<ViewStyle>;
|
||||
textStyle?: StyleProp<TextStyle>;
|
||||
}): ReactElement {
|
||||
const displayChord = chord ?? (keys ? [keys] : []);
|
||||
const shortcutOs = getShortcutOs();
|
||||
const singleCombo = displayChord[0];
|
||||
|
||||
if (!singleCombo) {
|
||||
return <View style={style} />;
|
||||
}
|
||||
|
||||
if (displayChord.length === 1) {
|
||||
return (
|
||||
<View style={[styles.badge, style]}>
|
||||
<Text style={[styles.text, textStyle]}>{formatShortcut(singleCombo, shortcutOs)}</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={[styles.root, style]}>
|
||||
<Text style={[styles.text, textStyle]}>{formatShortcut(keys, getShortcutOs())}</Text>
|
||||
<View style={[styles.sequence, style]}>
|
||||
{displayChord.map(function (combo, index) {
|
||||
return (
|
||||
<View key={`${combo.join("+")}-${index}`} style={styles.sequenceItem}>
|
||||
<View style={styles.badge}>
|
||||
<Text style={[styles.text, textStyle]}>{formatShortcut(combo, shortcutOs)}</Text>
|
||||
</View>
|
||||
{index < displayChord.length - 1 ? <Text style={styles.separator}>→</Text> : null}
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create((theme) => ({
|
||||
root: {
|
||||
badge: {
|
||||
paddingHorizontal: theme.spacing[1],
|
||||
paddingVertical: 2,
|
||||
borderRadius: theme.borderRadius.md,
|
||||
@@ -29,6 +56,21 @@ const styles = StyleSheet.create((theme) => ({
|
||||
borderWidth: theme.borderWidth[1],
|
||||
borderColor: theme.colors.borderAccent,
|
||||
},
|
||||
sequence: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
flexWrap: "wrap",
|
||||
gap: theme.spacing[1],
|
||||
},
|
||||
sequenceItem: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
gap: theme.spacing[1],
|
||||
},
|
||||
separator: {
|
||||
fontSize: theme.fontSize.xs,
|
||||
color: theme.colors.foregroundMuted,
|
||||
},
|
||||
text: {
|
||||
fontSize: theme.fontSize.xs,
|
||||
fontWeight: theme.fontWeight.normal,
|
||||
|
||||
Reference in New Issue
Block a user