mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-11-13 12:13:42 +01:00
Yaak Proxy: square app icons beside long names, and the final uncovered why line
App icons keep their square however a long app name squeezes them, in the card's buttons, the strip's Choose menu and the sidebar, and a long entry hint truncates instead of the button's label. A connection nothing on the list covers reads "Encrypted Content: Enable decryption to see requests to <host>", with the host as code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e3ff29ee6d
commit
c0f75bcfc2
7 files changed
+48
-16
No files matched your search
@@ -42,8 +42,13 @@ export function AppIcon({ path, className = "size-4" }: { path: string; classNam
|
|||||||
}, [path]);
|
}, [path]);
|
||||||
|
|
||||||
return url == null ? (
|
return url == null ? (
|
||||||
<span aria-hidden className={classNames(className, "inline-block shrink-0")} />
|
<span aria-hidden className={classNames(className, "inline-block shrink-0 aspect-square")} />
|
||||||
) : (
|
) : (
|
||||||
<img alt="" src={url} className={classNames(className, "shrink-0")} />
|
// Square whatever squeezes it, beside text that truncates
|
||||||
|
<img
|
||||||
|
alt=""
|
||||||
|
src={url}
|
||||||
|
className={classNames(className, "shrink-0 aspect-square object-contain")}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -185,6 +185,11 @@ function LineText({ line }: { line: Line }) {
|
|||||||
typeof part === "string" ? (
|
typeof part === "string" ? (
|
||||||
// oxlint-disable-next-line react/no-array-index-key -- the parts of one fixed line
|
// oxlint-disable-next-line react/no-array-index-key -- the parts of one fixed line
|
||||||
<span key={i}>{part}</span>
|
<span key={i}>{part}</span>
|
||||||
|
) : "bold" in part ? (
|
||||||
|
// oxlint-disable-next-line react/no-array-index-key -- the parts of one fixed line
|
||||||
|
<span key={i} className="font-semibold">
|
||||||
|
{part.bold}
|
||||||
|
</span>
|
||||||
) : (
|
) : (
|
||||||
// oxlint-disable-next-line react/no-array-index-key -- the parts of one fixed line
|
// oxlint-disable-next-line react/no-array-index-key -- the parts of one fixed line
|
||||||
<InlineCode key={i}>{part.code}</InlineCode>
|
<InlineCode key={i}>{part.code}</InlineCode>
|
||||||
@@ -222,7 +227,7 @@ function ActionButton({
|
|||||||
flow.clientPath == null ? (
|
flow.clientPath == null ? (
|
||||||
<Icon icon="box" size="sm" />
|
<Icon icon="box" size="sm" />
|
||||||
) : (
|
) : (
|
||||||
<AppIcon path={flow.clientPath} className="size-4" />
|
<AppIcon path={flow.clientPath} className="size-4 min-w-4" />
|
||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
<Icon icon={ICONS[action.icon]} size="sm" />
|
<Icon icon={ICONS[action.icon]} size="sm" />
|
||||||
@@ -241,7 +246,7 @@ function ActionButton({
|
|||||||
action.hint == null ? undefined : (
|
action.hint == null ? undefined : (
|
||||||
<span
|
<span
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"ml-auto pl-3 font-mono text-xs text-text-subtlest truncate max-w-[50%]",
|
"block ml-auto pl-3 font-mono text-xs text-text-subtlest truncate max-w-[11rem]",
|
||||||
action.removes && "line-through",
|
action.removes && "line-through",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -77,9 +77,9 @@ export function HttpsStrip() {
|
|||||||
app.path == null ? (
|
app.path == null ? (
|
||||||
app.name
|
app.name
|
||||||
) : (
|
) : (
|
||||||
<span className="flex items-center gap-2">
|
<span className="flex items-center gap-2 min-w-0">
|
||||||
<AppIcon path={app.path} className="size-4" />
|
<AppIcon path={app.path} className="size-4 min-w-4" />
|
||||||
{app.name}
|
<span className="truncate">{app.name}</span>
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
keepOpenOnSelect: true,
|
keepOpenOnSelect: true,
|
||||||
|
|||||||
@@ -85,7 +85,9 @@ function ItemInner({ item }: { item: SidebarItem }) {
|
|||||||
{item.kind === "encrypted" && <Icon icon="lock" size="sm" className="text-text-subtle" />}
|
{item.kind === "encrypted" && <Icon icon="lock" size="sm" className="text-text-subtle" />}
|
||||||
{item.kind === "saved" && <Icon icon="bookmark" size="sm" className="text-text-subtle" />}
|
{item.kind === "saved" && <Icon icon="bookmark" size="sm" className="text-text-subtle" />}
|
||||||
{item.kind === "folder" && <Icon icon="folder" size="sm" className="text-text-subtle" />}
|
{item.kind === "folder" && <Icon icon="folder" size="sm" className="text-text-subtle" />}
|
||||||
{item.appPath != null && <AppIcon path={item.appPath} className="size-[1.125rem]" />}
|
{item.appPath != null && (
|
||||||
|
<AppIcon path={item.appPath} className="size-[1.125rem] min-w-[1.125rem]" />
|
||||||
|
)}
|
||||||
{item.kind === "folder" && item.path != null ? (
|
{item.kind === "folder" && item.path != null ? (
|
||||||
// Named by its last part; the whole path on hover
|
// Named by its last part; the whole path on hover
|
||||||
<Tooltip wrap content={item.path} delay={CONTROL_TOOLTIP_DELAY}>
|
<Tooltip wrap content={item.path} delay={CONTROL_TOOLTIP_DELAY}>
|
||||||
|
|||||||
@@ -40,6 +40,12 @@ const apps = {
|
|||||||
clientBundleId: "com.1password.1password",
|
clientBundleId: "com.1password.1password",
|
||||||
clientPath: "/Applications/1Password.app",
|
clientPath: "/Applications/1Password.app",
|
||||||
},
|
},
|
||||||
|
headless: {
|
||||||
|
clientName: "chrome-headless-shell",
|
||||||
|
clientBundleId: null,
|
||||||
|
clientPath:
|
||||||
|
"/Users/you/.cache/ms-playwright/chromium_headless_shell-1208/chrome-headless-shell",
|
||||||
|
},
|
||||||
acme: {
|
acme: {
|
||||||
clientName: "Acme Sync",
|
clientName: "Acme Sync",
|
||||||
clientBundleId: "dev.acme.sync",
|
clientBundleId: "dev.acme.sync",
|
||||||
@@ -124,6 +130,7 @@ function encryptedScene(): Flow[] {
|
|||||||
tunnel(10, "fonts.gstatic.com", apps.dia),
|
tunnel(10, "fonts.gstatic.com", apps.dia),
|
||||||
tunnel(11, "clients2.google.com", apps.chrome),
|
tunnel(11, "clients2.google.com", apps.chrome),
|
||||||
tunnel(12, "home.taila714c.ts.net:8317", apps.dia, { url: "home.taila714c.ts.net:8317" }),
|
tunnel(12, "home.taila714c.ts.net:8317", apps.dia, { url: "home.taila714c.ts.net:8317" }),
|
||||||
|
tunnel(13, "optimizationguide-pa.googleapis.com", apps.headless),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,9 @@ describe("the card of an encrypted connection", () => {
|
|||||||
|
|
||||||
test("something else listed: not on the list, with the same choices", () => {
|
test("something else listed: not on the list, with the same choices", () => {
|
||||||
const c = card({ list: [...user("host:api.stripe.com"), ...BUILT_INS] });
|
const c = card({ list: [...user("host:api.stripe.com"), ...BUILT_INS] });
|
||||||
expect(lineText(c.why)).toBe("Decryption not configured for `www.google.com`");
|
expect(lineText(c.why)).toBe(
|
||||||
|
"**Encrypted Content:** Enable decryption to see requests to `www.google.com`",
|
||||||
|
);
|
||||||
expect(c.actions.map((a) => a.label)).toEqual([
|
expect(c.actions.map((a) => a.label)).toEqual([
|
||||||
"Decrypt www.google.com",
|
"Decrypt www.google.com",
|
||||||
"Decrypt Dia",
|
"Decrypt Dia",
|
||||||
@@ -108,10 +110,10 @@ describe("the card of an encrypted connection", () => {
|
|||||||
test("names the host nothing on the list covers, its port only when not 443", () => {
|
test("names the host nothing on the list covers, its port only when not 443", () => {
|
||||||
const list = [...user("host:api.stripe.com"), ...BUILT_INS];
|
const list = [...user("host:api.stripe.com"), ...BUILT_INS];
|
||||||
expect(lineText(card({ list, flow: { ...tunnel, url: "t.yaak.app:443" } }).why)).toBe(
|
expect(lineText(card({ list, flow: { ...tunnel, url: "t.yaak.app:443" } }).why)).toBe(
|
||||||
"Decryption not configured for `t.yaak.app`",
|
"**Encrypted Content:** Enable decryption to see requests to `t.yaak.app`",
|
||||||
);
|
);
|
||||||
expect(lineText(card({ list, flow: { ...tunnel, url: "home.ts.net:8317" } }).why)).toBe(
|
expect(lineText(card({ list, flow: { ...tunnel, url: "home.ts.net:8317" } }).why)).toBe(
|
||||||
"Decryption not configured for `home.ts.net:8317`",
|
"**Encrypted Content:** Enable decryption to see requests to `home.ts.net:8317`",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -78,12 +78,19 @@ export interface CardAction {
|
|||||||
icon: "host" | "app" | "everything" | "lock" | "lock_open" | "refresh" | "shield" | "terminal";
|
icon: "host" | "app" | "everything" | "lock" | "lock_open" | "refresh" | "shield" | "terminal";
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A line of text, the hosts, apps and entries in it shown as code, as Yaak shows literal values */
|
/**
|
||||||
export type Line = (string | { code: string })[];
|
* A line of text, the hosts, apps and entries in it shown as code, as Yaak shows literal values,
|
||||||
|
* and a lead in bold
|
||||||
|
*/
|
||||||
|
export type Line = (string | { code: string } | { bold: string })[];
|
||||||
|
|
||||||
/** A line as plain text, its code in backticks */
|
/** A line as plain text, its code in backticks and its bold in asterisks */
|
||||||
export function lineText(line: Line): string {
|
export function lineText(line: Line): string {
|
||||||
return line.map((part) => (typeof part === "string" ? part : `\`${part.code}\``)).join("");
|
return line
|
||||||
|
.map((part) =>
|
||||||
|
typeof part === "string" ? part : "code" in part ? `\`${part.code}\`` : `**${part.bold}**`,
|
||||||
|
)
|
||||||
|
.join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EncryptedCardModel {
|
export interface EncryptedCardModel {
|
||||||
@@ -265,7 +272,11 @@ function whyLine(
|
|||||||
? ["Nothing is decrypted yet"]
|
? ["Nothing is decrypted yet"]
|
||||||
: decryptsNow
|
: decryptsNow
|
||||||
? ["Not on the decrypt list"]
|
? ["Not on the decrypt list"]
|
||||||
: ["Decryption not configured for ", { code: c.label }],
|
: [
|
||||||
|
{ bold: "Encrypted Content:" },
|
||||||
|
" Enable decryption to see requests to ",
|
||||||
|
{ code: c.label },
|
||||||
|
],
|
||||||
whySub: null,
|
whySub: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user