The mention chips of a selected chat message go white with its text
In a channel, a DM, or a room, the selected message's text is white, and now its mention chips follow: the label turns white and the fill stays, so the chips still tell one node from the next. Arrow mode whitens the label the same way. A mention that no key can place keeps its grey, as on every selected row. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
59273a6b29
commit
7264a71104
4 files changed
+68
-3
No files matched your search
@@ -592,7 +592,10 @@ as a grouped list does. Filling a page in is editing its `.md`; no Python follow
|
||||
what a route graph's one-byte labels are matched by — so `pathline` stamps its own extent
|
||||
(`PATH_INK`, a style that draws nothing) and the fold skips what lies inside it. That is
|
||||
what makes the arrow form say what the chip form always said, its fills having never been
|
||||
in the fold's vocabulary. Reverse-video chips — a dialog's committing button,
|
||||
in the fold's vocabulary. The one exception is a chat's **selected message**: its mention
|
||||
chips go white with its text (JP, 2026-10-19) — the label only, the fill kept, keyed hues
|
||||
only (`widgets.picked_hop`: `white_ink` on a chip, `cursor` in arrow mode). A mention is
|
||||
a name in prose, not a hop of a route. Reverse-video chips — a dialog's committing button,
|
||||
a running action's Abort, the arrow-mode composer slot, the editor cursor — are the
|
||||
`selected` fill, a **grey** block (`muted`'s grey; light grey slot 7 on the VT, the one
|
||||
grey a reverse can put behind text there, and the same fill the F-key lane uses). A chip
|
||||
|
||||
+8
-1
@@ -51,6 +51,7 @@ from .widgets import (
|
||||
hop_chip,
|
||||
mention_hop,
|
||||
mention_mark,
|
||||
picked_hop,
|
||||
self_chip,
|
||||
)
|
||||
|
||||
@@ -910,6 +911,9 @@ class ChatScreen(Screen):
|
||||
whose chip closes on the point). The chip has no ``@``, because the chip already
|
||||
says that the name is a mention (JP, 2026-10-13). Arrow mode has no chip, so there a
|
||||
mention keeps its ``@`` (refer to :func:`~meshterm.ui.widgets.mention_hop`).
|
||||
|
||||
On the selected message, the label of each chip is white, as the text around it is
|
||||
(refer to :func:`~meshterm.ui.widgets.picked_hop`, JP, 2026-10-19).
|
||||
"""
|
||||
base = "cursor" if selected else None
|
||||
text = Text()
|
||||
@@ -917,7 +921,10 @@ class ChatScreen(Screen):
|
||||
for match in MENTION.finditer(body):
|
||||
if match.start() > pos:
|
||||
text.append(body[pos : match.start()], style=base)
|
||||
text.append_text(hop_chip(self._mention_hop(match.group(1)), role=DESTINATION))
|
||||
hop = self._mention_hop(match.group(1))
|
||||
if selected:
|
||||
hop = picked_hop(hop) # the chips turn white with the text around them
|
||||
text.append_text(hop_chip(hop, role=DESTINATION))
|
||||
pos = match.end()
|
||||
if pos < len(body):
|
||||
text.append(body[pos:], style=base)
|
||||
|
||||
+22
-1
@@ -5,7 +5,7 @@ from __future__ import annotations
|
||||
|
||||
import math
|
||||
from collections.abc import Callable, Sequence
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import dataclass, field, replace
|
||||
from datetime import datetime
|
||||
from itertools import pairwise
|
||||
from typing import TYPE_CHECKING
|
||||
@@ -789,6 +789,27 @@ def mention_hop(name: str, key: str | None, *, you: bool = False) -> PathHop:
|
||||
return PathHop(label, key=key or None, white_ink=you and bool(key), quiet=True)
|
||||
|
||||
|
||||
def picked_hop(hop: PathHop) -> PathHop:
|
||||
"""``hop`` on the selected message of a chat: its label in the white of the selection.
|
||||
|
||||
The text of the selected message is white (``cursor``), and its chips follow it (JP,
|
||||
2026-10-19). A chip keeps its fill, so it still tells one node from the next, and only
|
||||
its label turns white: the white label of our own chip
|
||||
(:attr:`~meshterm.ui.pathline.PathHop.white_ink`). Arrow mode has no fill, so there the
|
||||
label takes the ``cursor`` white, as each other name on a selected row does.
|
||||
|
||||
The rule is the rule of the white fold of a selected row (refer to
|
||||
:func:`~meshterm.ui.tui.render._whiten_identities`): only the hue of a key turns white.
|
||||
A node that no key can place keeps its grey, because the selection must not claim to
|
||||
know that node. A hop that already has a white label stays as it is.
|
||||
"""
|
||||
if not hop.key or hop.white_ink:
|
||||
return hop
|
||||
if powerline_enabled():
|
||||
return replace(hop, white_ink=True)
|
||||
return replace(hop, style="cursor")
|
||||
|
||||
|
||||
def mention_chip(name: str, key: str | None, *, you: bool = False) -> Text:
|
||||
"""A mention in a message: the chip of the node that it names, which opens on the notch.
|
||||
|
||||
|
||||
@@ -3254,6 +3254,40 @@ def test_a_locked_author_has_the_padlock_on_its_sender_chip(
|
||||
assert "\U0001f512" not in shown and "Alice" in shown
|
||||
|
||||
|
||||
@pytest.mark.parametrize("chips", [True, False])
|
||||
def test_the_chips_of_the_selected_message_turn_white_with_its_text(
|
||||
powerline, # noqa: ANN001
|
||||
chips: bool,
|
||||
) -> None:
|
||||
"""On the selected message, a mention chip has a white label, as the text around it does.
|
||||
|
||||
JP, 2026-10-19. A chip keeps its fill, so it still tells one node from the next. In
|
||||
arrow mode, the label takes the ``cursor`` white. A node that no key can place keeps its
|
||||
grey, as on each selected row: the selection must not claim to know that node.
|
||||
"""
|
||||
powerline(chips)
|
||||
keys = {"alice": "a1" * 32, "bob": "b2" * 32}
|
||||
body = "hi @[Bob] and @[Zed]"
|
||||
screen = ChatScreen(
|
||||
Conversation(label="#public", is_channel=True, channel_idx=0),
|
||||
[ChatMessage(text=f"Alice: {body}", is_channel=True, channel_idx=0)],
|
||||
send=None,
|
||||
names={},
|
||||
session=_StubSession(),
|
||||
key_of=lambda name: keys.get(name.casefold()),
|
||||
)
|
||||
|
||||
def styles(label: str, *, selected: bool) -> str:
|
||||
text = screen._render_mentions(body, selected=selected)
|
||||
at = text.plain.index(label)
|
||||
return " ".join(str(s.style) for s in text.spans if s.start <= at < s.end)
|
||||
|
||||
white = "#ffffff" if chips else "cursor"
|
||||
assert white in styles("Bob", selected=True)
|
||||
assert white not in styles("Bob", selected=False)
|
||||
assert white not in styles("Zed", selected=True)
|
||||
|
||||
|
||||
def test_the_lock_atom_never_pushes_another_key_out_of_the_hint(tmp_path: Path) -> None:
|
||||
"""With a link and a location, the hint has no room for ^K, so the atom stays out.
|
||||
|
||||
|
||||
Reference in new issue
Block a user