Compare commits
2
Commits
49c7da2381
...
v0.0.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ed9a57822
|
||
|
|
0601098ab0
|
@@ -6,6 +6,14 @@ Sections are written by hand. Nothing here is generated from commit messages: th
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [0.0.5] - 2026-08-16
|
||||||
|
|
||||||
|
One rendering fix on the 0.0.4 feature, caught the day it shipped.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- The query tables no longer repeat the *learned* tag on every row: in the live page and the query log a learned name is just muted, with the address still in the row's tooltip. The clients page keeps the tag, where it appears once per client and says something.
|
||||||
|
|
||||||
## [0.0.4] - 2026-08-16
|
## [0.0.4] - 2026-08-16
|
||||||
|
|
||||||
The names learned in 0.0.3 now show up where queries do: the live page and the query log name each client instead of printing its address.
|
The names learned in 0.0.3 now show up where queries do: the live page and the query log name each client instead of printing its address.
|
||||||
|
|||||||
@@ -3,6 +3,11 @@
|
|||||||
* with the same precedence the Clients page applies: a hand-typed `name` wins,
|
* with the same precedence the Clients page applies: a hand-typed `name` wins,
|
||||||
* the reverse-DNS `learned_name` stands in muted behind it, and an address with
|
* the reverse-DNS `learned_name` stands in muted behind it, and an address with
|
||||||
* neither — including one the loaded list has never seen — stays bare.
|
* neither — including one the loaded list has never seen — stays bare.
|
||||||
|
*
|
||||||
|
* The muted colour is the whole of the affordance here. The Clients page pairs
|
||||||
|
* it with an outlined "learned" tag, and keeps it: one mention per client is
|
||||||
|
* information. Repeating that tag down every row of a query table is noise, so
|
||||||
|
* the tables carry the name alone.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
@@ -43,7 +48,6 @@ export function ClientName({ ip, names }: { ip: string; names: ClientNames }) {
|
|||||||
return (
|
return (
|
||||||
<span title={ip} {...stylex.props(shared.learnedName)}>
|
<span title={ip} {...stylex.props(shared.learnedName)}>
|
||||||
{client.learned_name}
|
{client.learned_name}
|
||||||
<span {...stylex.props(shared.learnedTag)}>learned</span>
|
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,14 +131,11 @@ test("resolves each row's client to its display name, keeping the IP as the tool
|
|||||||
expect(named.getAttribute("title")).toBe("192.0.2.10");
|
expect(named.getAttribute("title")).toBe("192.0.2.10");
|
||||||
expect(screen.queryByText("pi.lan")).toBeNull();
|
expect(screen.queryByText("pi.lan")).toBeNull();
|
||||||
|
|
||||||
// The cell holds the learned name followed by the tag, so the match is on
|
// A learned name reads muted and nothing more here: the "learned" tag would
|
||||||
// the containing span rather than on a bare text node.
|
// repeat on every row of the table, so the Clients page carries it instead.
|
||||||
const learned = screen.getByText(
|
const learned = screen.getByText("laptop.lan");
|
||||||
(content, element) => element?.tagName === "SPAN" && content.startsWith("laptop.lan"),
|
|
||||||
);
|
|
||||||
expect(learned.getAttribute("title")).toBe("192.0.2.11");
|
expect(learned.getAttribute("title")).toBe("192.0.2.11");
|
||||||
// The affordance is text, not colour, so a screen reader announces it too.
|
expect(within(learned.closest("tr")!).queryByText("learned")).toBeNull();
|
||||||
expect(within(learned).getByText("learned")).toBeTruthy();
|
|
||||||
|
|
||||||
// A known client with neither name, and a client the loaded list has never
|
// A known client with neither name, and a client the loaded list has never
|
||||||
// seen, both fall back to the bare address with no tooltip standing in.
|
// seen, both fall back to the bare address with no tooltip standing in.
|
||||||
|
|||||||
@@ -137,14 +137,11 @@ test("resolves each row's client to its display name, keeping the IP as the tool
|
|||||||
expect(named.getAttribute("title")).toBe("192.0.2.10");
|
expect(named.getAttribute("title")).toBe("192.0.2.10");
|
||||||
expect(screen.queryByText("pi.lan")).toBeNull();
|
expect(screen.queryByText("pi.lan")).toBeNull();
|
||||||
|
|
||||||
// The cell holds the learned name followed by the tag, so the match is on
|
// A learned name reads muted and nothing more here: the "learned" tag would
|
||||||
// the containing span rather than on a bare text node.
|
// repeat on every row of the table, so the Clients page carries it instead.
|
||||||
const learned = screen.getByText(
|
const learned = screen.getByText("laptop.lan");
|
||||||
(content, element) => element?.tagName === "SPAN" && content.startsWith("laptop.lan"),
|
|
||||||
);
|
|
||||||
expect(learned.getAttribute("title")).toBe("192.0.2.11");
|
expect(learned.getAttribute("title")).toBe("192.0.2.11");
|
||||||
// The affordance is text, not colour, so a screen reader announces it too.
|
expect(within(learned.closest("tr")!).queryByText("learned")).toBeNull();
|
||||||
expect(within(learned).getByText("learned")).toBeTruthy();
|
|
||||||
|
|
||||||
// A known client with neither name, and a client the loaded list has never
|
// A known client with neither name, and a client the loaded list has never
|
||||||
// seen, both fall back to the bare address with no tooltip standing in.
|
// seen, both fall back to the bare address with no tooltip standing in.
|
||||||
|
|||||||
@@ -169,8 +169,10 @@ export const styles = stylex.create({
|
|||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* A learned name is runtime state, not something the operator typed, so it
|
* A learned name is runtime state, not something the operator typed, so it
|
||||||
* reads muted and carries an outlined "learned" tag. The tag is real text —
|
* reads muted wherever it appears. The Clients page adds the outlined tag,
|
||||||
* a screen reader announces it — because colour alone is not an affordance.
|
* where the client is named once; the query tables leave it off rather than
|
||||||
|
* repeat it on every row. The tag is real text — a screen reader announces
|
||||||
|
* it — because colour alone is not an affordance.
|
||||||
*/
|
*/
|
||||||
learnedName: {
|
learnedName: {
|
||||||
color: colors.textMuted,
|
color: colors.textMuted,
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
.{
|
.{
|
||||||
.name = .nxdns,
|
.name = .nxdns,
|
||||||
.version = "0.0.4",
|
.version = "0.0.5",
|
||||||
.minimum_zig_version = "0.16.0",
|
.minimum_zig_version = "0.16.0",
|
||||||
.paths = .{""},
|
.paths = .{""},
|
||||||
.fingerprint = 0x3307b311dded1d91,
|
.fingerprint = 0x3307b311dded1d91,
|
||||||
|
|||||||
Reference in New Issue
Block a user