From d12beda8a9375d75dbe9b43b21e830e9be6c4635 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 10 Nov 2026 11:06:02 -0700 Subject: [PATCH] Keep Clear in the header with Cmd+Shift+K in its tooltip, and leave the port to the menu's address line Co-Authored-By: Claude Opus 5.5 --- ...learFlowsMenu.tsx => ClearFlowsButton.tsx} | 51 +++++++----- apps/yaak-proxy/components/FlowDetail.tsx | 2 +- apps/yaak-proxy/components/ProxyLayout.tsx | 2 + apps/yaak-proxy/components/ProxyStatus.tsx | 78 ++++++++----------- crates-proxy/yaak-proxy-lib/src/actions.rs | 2 +- 5 files changed, 65 insertions(+), 70 deletions(-) rename apps/yaak-proxy/components/{ClearFlowsMenu.tsx => ClearFlowsButton.tsx} (58%) diff --git a/apps/yaak-proxy/components/ClearFlowsMenu.tsx b/apps/yaak-proxy/components/ClearFlowsButton.tsx similarity index 58% rename from apps/yaak-proxy/components/ClearFlowsMenu.tsx rename to apps/yaak-proxy/components/ClearFlowsButton.tsx index 687d21546..157fe0a17 100644 --- a/apps/yaak-proxy/components/ClearFlowsMenu.tsx +++ b/apps/yaak-proxy/components/ClearFlowsButton.tsx @@ -1,28 +1,19 @@ -import { Dropdown, type DropdownItem, type DropdownRef } from "@yaakapp-internal/ui"; +import { Dropdown, type DropdownItem, IconButton, useFormattedHotkey } from "@yaakapp-internal/ui"; import { useAtomValue, useSetAtom } from "jotai"; -import type { Ref } from "react"; import { useState } from "react"; import { clearFlowsAtom, flowTotalAtom, lockedAtom } from "../lib/store"; -/** Whether there are flows to clear: some, and readable, as they aren't while traffic is locked */ -export function useCanClearFlows(): boolean { - const total = useAtomValue(flowTotalAtom); - const locked = useAtomValue(lockedAtom); - return locked == null && total > 0; -} - /** - * Clears every flow, once confirmed in its menu, which its hotkey or the status menu's Clear - * Traffic opens. It has no button of its own: it covers the element it is placed over, without - * taking the pointer, so the menu opens from there. The list empties at once; the flows are - * deleted in the background. Neither menu nor hotkey with nothing to clear, or while captured + * Clears every flow, once confirmed in its menu, which its hotkey opens too. The list empties at + * once; the flows are deleted in the background. Disabled with none to clear, or while captured * traffic is locked. */ -export function ClearFlowsMenu({ ref }: { ref?: Ref }) { +export function ClearFlowsButton() { const total = useAtomValue(flowTotalAtom); - const canClear = useCanClearFlows(); + const locked = useAtomValue(lockedAtom); const clear = useSetAtom(clearFlowsAtom); const [error, setError] = useState(null); + const hotkey = useFormattedHotkey("flows_clear")?.join(""); const items: DropdownItem[] = [ { @@ -57,13 +48,31 @@ export function ClearFlowsMenu({ ref }: { ref?: Ref }) { }, ]; + // Nothing to clear, or nothing that can be read while traffic is locked: no menu, nor hotkey. + if (locked != null || total === 0) { + return ( + + ); + } + return ( - - + + ); } diff --git a/apps/yaak-proxy/components/FlowDetail.tsx b/apps/yaak-proxy/components/FlowDetail.tsx index e4ad2a420..3a2edbf90 100644 --- a/apps/yaak-proxy/components/FlowDetail.tsx +++ b/apps/yaak-proxy/components/FlowDetail.tsx @@ -31,7 +31,7 @@ export function FlowDetail({ style, sideBySide }: { style?: CSSProperties; sideB Pause or resume recording - Clear traffic + Clear flows diff --git a/apps/yaak-proxy/components/ProxyLayout.tsx b/apps/yaak-proxy/components/ProxyLayout.tsx index 842c9abed..0d11364d5 100644 --- a/apps/yaak-proxy/components/ProxyLayout.tsx +++ b/apps/yaak-proxy/components/ProxyLayout.tsx @@ -18,6 +18,7 @@ import { proxyStatusOf, statusTintColor } from "../lib/proxyStatus"; import { lockedAtom, noFlowsAtom, proxyStateAtom, systemProxyEverOnAtom } from "../lib/store"; import { getOsType } from "../lib/tauri"; import { AddColumnDialog } from "./AddColumnDialog"; +import { ClearFlowsButton } from "./ClearFlowsButton"; import { FirstRun } from "./FirstRun"; import { FlowDetail } from "./FlowDetail"; import { FlowList } from "./FlowList"; @@ -95,6 +96,7 @@ export function ProxyLayout() {
+ (null); - const clearRef = useRef(null); - const canClear = useCanClearFlows(); const [copied, setCopied] = useCopied(); const proxyState = useAtomValue(proxyStateAtom); const setup = useProxySetup(); @@ -134,17 +131,6 @@ export function ProxyStatus() { hotKeyLabelOnly: true, onSelect: () => execute.mutate({ scope: "global", action: "recording_toggle" }), }, - { - label: "Clear Traffic", - icon: "trash", - disabled: !canClear, - hotKeyAction: "flows_clear", - hotKeyLabelOnly: true, - // Its confirmation opens from the pill once this menu has closed. - onSelect: () => { - setTimeout(() => clearRef.current?.open()); - }, - }, { type: "separator" }, { type: "content", @@ -222,36 +208,33 @@ export function ProxyStatus() { return ( <> - - - - {status === "encrypting" ? ( - <> - - Encrypting - {encrypting} - - ) : status === "cli" && other != null ? ( - <> - - CLI - - ) : status === "recording" || status === "paused" ? ( - <> - - {recording ? "Recording" : "Paused"} - - ) : ( - <> - - Not running - - )} - - - - - + + + {status === "encrypting" ? ( + <> + + Encrypting + {encrypting} + + ) : status === "cli" && other != null ? ( + <> + + CLI + + ) : status === "recording" || status === "paused" ? ( + <> + + {recording ? "Recording" : "Paused"} + + ) : ( + <> + + Not running + + )} + + + {untrusted && ( dropdownRef.current?.open()}> @@ -337,6 +320,7 @@ export function useCopyEnvironment() { } }; } + /** Whether something was just copied, for a moment, and the call that says it was */ function useCopied(): [boolean, () => void] { const [copied, setCopied] = useState(false); diff --git a/crates-proxy/yaak-proxy-lib/src/actions.rs b/crates-proxy/yaak-proxy-lib/src/actions.rs index ed40a59c9..cf35d098e 100644 --- a/crates-proxy/yaak-proxy-lib/src/actions.rs +++ b/crates-proxy/yaak-proxy-lib/src/actions.rs @@ -43,7 +43,7 @@ pub fn all_global_actions() -> Vec<(ActionInvocation, ActionMetadata)> { ( ActionInvocation::Global { action: GlobalAction::FlowsClear }, ActionMetadata { - label: "Clear Traffic".into(), + label: "Clear Flows".into(), // Not Cmd+K, which is kept for a command palette. default_hotkey: default_hotkey("Meta+Shift+K", "Ctrl+Shift+K"), },