In a chat, our sender chip has its star inside again
Our messages go under "★ Name" on the turned-over chip, as before the last change. A mention of us keeps its chip without a star, and its message keeps the star at the left of the time. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
8043881d3c
commit
427bee836b
8 files changed
+51
-67
No files matched your search
+7
-7
@@ -12,13 +12,13 @@ can change how things behave. It does not only add new things.
|
||||
### Changed
|
||||
|
||||
- **In a chat, your messages show your name.** A channel, a direct chat, and a room put
|
||||
your messages under your node's name, with a `★` after it, and the Messages list shows
|
||||
them in the same way. Your name has the colour of your key, but in reverse: dark text on
|
||||
a light fill, where each other sender has light text on a dark fill. A mention of your
|
||||
name has the same reversed colours, and the message that has it gets a `★` at the left
|
||||
of its time. Thus the messages that name you are easy to find down the left side of the
|
||||
chat. On the PicoCalc, the console cannot draw a light fill, so there the `★` alone
|
||||
marks you. Before, your messages showed only the `★`.
|
||||
your messages under `★` and your node's name, and the Messages list shows them in the
|
||||
same way. Your name has the colour of your key, but in reverse: dark text on a light
|
||||
fill, where each other sender has light text on a dark fill. A mention of your name has
|
||||
the same reversed colours, and the message that has it gets a `★` at the left of its
|
||||
time. Thus the messages that name you are easy to find down the left side of the chat.
|
||||
On the PicoCalc, the console cannot draw a light fill, so there the `★` alone marks you.
|
||||
Before, your messages showed only the `★`.
|
||||
- **A mention has no `@` in front of it.** The coloured box around the name already says
|
||||
that it is a mention. On a terminal that cannot draw the boxes, a mention keeps its `@`.
|
||||
- **The line where you write a message shows each mention as a box.** When you type the
|
||||
|
||||
@@ -484,16 +484,15 @@ as a grouped list does. Filling a page in is editing its `.md`; no Python follow
|
||||
but a chat is a conversation between names, so our sender chip and every mention of our
|
||||
name wear our name on the chip of *our key's hue, turned over* — dark ink on a light
|
||||
fill of the hue (`PathHop.inverse`, the same pair as any chip in the other order), the
|
||||
one light chip among the senders. **The `★` never sits inside that chip** (a yellow star
|
||||
measured under 3:1 on the light fill for 238 of 256 hues, and in the chip's dark ink it
|
||||
read as part of the name; JP, 2026-10-13): our sender chip is `Name ★`, the map's
|
||||
yellow star on the page one cell right of the chip (`widgets.self_chip`); a mention of
|
||||
us is the turned-over chip alone (`mention_chip(you=True)`), and the message carrying
|
||||
it gets the `★` in the two cells left of its time (`❯ ★ 12:34 body` — every time sits
|
||||
two cells right to keep the column; the Messages list puts it left of the row's age).
|
||||
Arrow mode draws the chip as a padded reverse-video block. The PicoCalc can't put a
|
||||
bright slot behind text, so there the chip keeps the normal colours and the `★` alone
|
||||
marks us. With no name or key from the device, the bare `★` chip stays. Path lines
|
||||
one light chip among the senders. Our **sender** chip is `★ Name` (`widgets.self_chip`),
|
||||
the star in the chip's dark ink: a yellow star measured under 3:1 on the light fill for
|
||||
238 of 256 hues, and the star on the page right of the chip was tried and put back (JP,
|
||||
2026-10-13). A **mention** of us is the turned-over chip with no star
|
||||
(`mention_chip(you=True)`); the message carrying it gets the `★` in the two cells left
|
||||
of its time instead (`❯ ★ 12:34 body` — every time sits two cells right to keep the
|
||||
column; the Messages list puts it left of the row's age). Arrow mode draws the chip as
|
||||
a padded reverse-video block. The PicoCalc can't put a bright slot behind text, so
|
||||
there the chip keeps the normal colours and the `★` alone marks us. With no name or key from the device, the bare `★` chip stays. Path lines
|
||||
(delivery paths, the packet viewer, routes) keep `★`.
|
||||
- **The compose line draws a mention as its chip** (`ui/compose.py`, `MentionEditor`): the
|
||||
moment `]` completes an `@[Name]` token it renders as the same chip the transcript will
|
||||
|
||||
@@ -1055,10 +1055,10 @@ def _preview_text(
|
||||
|
||||
It is the same as the live transcript:
|
||||
|
||||
- Our own messages start with our name on a chip that is turned over, with the ``★``
|
||||
after it (refer to :func:`~meshterm.ui.widgets.self_chip`). A mention of our name
|
||||
has the chip that is turned over, with no star. The star of a message that names us
|
||||
is at the left of the age of the row (refer to :func:`_title`).
|
||||
- Our own messages start with our chip, ``★ Name`` turned over (refer to
|
||||
:func:`~meshterm.ui.widgets.self_chip`). A mention of our name has the chip that is
|
||||
turned over, with no star. The star of a message that names us is at the left of the
|
||||
age of the row (refer to :func:`_title`).
|
||||
- In a received channel message, the inline ``Name:`` sender is the author, in the hue
|
||||
that comes from its key (the node grey when no known node has the name).
|
||||
- A room post starts with its author, named by key in the same way as the room screen
|
||||
|
||||
+3
-4
@@ -729,10 +729,9 @@ class ChatScreen(Screen):
|
||||
chip of a path line (refer to :func:`~meshterm.ui.widgets.name_chip`). Thus a
|
||||
sender looks exactly like that node as a hop in a route.
|
||||
|
||||
Our messages are the exception. They go under our name, on a chip that is turned
|
||||
over, with the ``★`` to the right of the chip (refer to
|
||||
:func:`~meshterm.ui.widgets.self_chip`). A route shows our end as the bare ``★``,
|
||||
but a chat is a conversation between names.
|
||||
Our messages are the exception. They go under our name, as ``★ Name`` on a chip
|
||||
that is turned over (refer to :func:`~meshterm.ui.widgets.self_chip`). A route
|
||||
shows our end as the bare ``★``, but a chat is a conversation between names.
|
||||
Our chip comes from the direction of the message (``outbound``), not from the
|
||||
``"you"`` label. Thus a remote sender with the name ``you`` still gets the hue of
|
||||
its key, and does not look like our node.
|
||||
|
||||
@@ -146,9 +146,9 @@ def specimen_lines() -> list[RenderableType]:
|
||||
# notch, because the node that it names is where the message goes, and it has no ``@``.
|
||||
# The path line's own segment draws them, so this row is also a one-hop sample of the
|
||||
# route language: the hue in the fill and the keyless grey for a node that nobody can
|
||||
# identify. Our own messages go under ``me``, on the one chip that is turned over (dark
|
||||
# on a light fill of our hue), with the ``★`` after it. The console of the PicoCalc has
|
||||
# no light background, so there only the star marks it.
|
||||
# identify. Our own messages go under ``★ me``, on the one chip that is turned over
|
||||
# (dark on a light fill of our hue). The console of the PicoCalc has no light
|
||||
# background, so there only the star marks it.
|
||||
chips = Text("chips ")
|
||||
for name, key in _DEMO_NAMES[:2]:
|
||||
chips.append_text(name_chip(name, key, role=ORIGIN))
|
||||
|
||||
+9
-13
@@ -684,17 +684,17 @@ def name_chip(
|
||||
|
||||
|
||||
def self_chip(name: str | None, key: str | None, *, role: str | None = None) -> Text:
|
||||
"""Our node as the sender in a chat: ``Name ★``, a chip that is turned over, then the star.
|
||||
"""Our node as the sender in a chat: ``★ Name``, on the chip of our key, turned over.
|
||||
|
||||
A chat (a channel, a direct chat, a room) names each sender, and our node too. A route
|
||||
shows our end as the bare ``★``, because the user never has to be told who that is. A
|
||||
chat is a conversation between names, so our messages go under our name (JP,
|
||||
2026-10-13). Two things make it different from the name of each other node. The chip
|
||||
is turned over: the other senders are a light hue on a dark fill, and ours is dark on a
|
||||
light fill of our hue. Also, the ``★`` of the app is on the page to the right of the
|
||||
chip, in the yellow of the map (JP, 2026-10-13). In the chip, the star had the dark
|
||||
ink of the chip. The console of the PicoCalc cannot draw a light background, so there
|
||||
the chip keeps the colours of each other chip and the star alone marks us (refer to
|
||||
2026-10-13). Two things make it different from the name of each other node. The ``★``
|
||||
of the app comes first, in the dark ink of the chip. Also, the chip is turned over: the
|
||||
other senders are a light hue on a dark fill, and ours is dark on a light fill of our
|
||||
hue. A star on the page to the right of the chip was tried, and JP put it back in the
|
||||
chip (2026-10-13). The console of the PicoCalc cannot draw a light background, so
|
||||
there the chip keeps the colours of each other chip and the ``★`` marks us (refer to
|
||||
:attr:`~meshterm.ui.pathline.PathHop.inverse`).
|
||||
|
||||
A mention of our name is a different mark (refer to :func:`mention_chip`). The chip is
|
||||
@@ -710,15 +710,11 @@ def self_chip(name: str | None, key: str | None, *, role: str | None = None) ->
|
||||
role: :data:`ORIGIN`, :data:`DESTINATION`, or ``None``, as for :func:`name_chip`.
|
||||
|
||||
Returns:
|
||||
The chip and the star as a one-line :class:`Text`.
|
||||
The chip as a one-line :class:`Text`.
|
||||
"""
|
||||
if not name or not key:
|
||||
return name_chip("", you=True, role=role)
|
||||
line = Text()
|
||||
line.append_text(hop_chip(PathHop(name, key=key, inverse=True), role=role))
|
||||
line.append(" ")
|
||||
line.append(SELF_MARK[0], style="type.you")
|
||||
return line
|
||||
return hop_chip(PathHop(f"{SELF_GLYPH} {name}", key=key, inverse=True), role=role)
|
||||
|
||||
|
||||
def mention_hop(name: str, key: str | None, *, you: bool = False) -> PathHop:
|
||||
|
||||
+11
-12
@@ -448,9 +448,8 @@ def test_preview_prefixes_own_messages_only() -> None:
|
||||
assert _preview_text(dm_in, _NO_KEYS).plain == "hey"
|
||||
mine = ChatMessage(text="yo", outbound=True, is_channel=True, channel_idx=0)
|
||||
assert _preview_text(mine, _NO_KEYS).plain == "you: yo" # our node with no name
|
||||
# With our name, the preview shows our chat chip (a padded block in reverse video),
|
||||
# then the star.
|
||||
assert _preview_text(mine, _NO_KEYS, us=("Me", _OUR_KEY)).plain == " Me ★ yo"
|
||||
# With our name, the preview shows our chat chip: a padded block in reverse video.
|
||||
assert _preview_text(mine, _NO_KEYS, us=("Me", _OUR_KEY)).plain == " ★ Me yo"
|
||||
|
||||
|
||||
def test_preview_colours_channel_sender_and_mentions() -> None:
|
||||
@@ -475,9 +474,9 @@ def test_preview_draws_the_author_and_the_mentions_as_the_transcript_does(powerl
|
||||
"""With chips, the author closes on the point and a mention opens on the notch.
|
||||
|
||||
The point says what the colon said, so the chip has no colon, and a mention chip has
|
||||
no ``@``. Our own author is our name and then the ``★``, as the sender chip of our
|
||||
messages in the transcript. A mention of our name has no star. With no name for our
|
||||
node, the bare ``★`` stays.
|
||||
no ``@``. Our own author is ``★ Name``, as the sender chip of our messages in the
|
||||
transcript. A mention of our name has no star. With no name for our node, the bare
|
||||
``★`` stays.
|
||||
"""
|
||||
from meshterm.ui.pathline import POWERLINE_ROUND_CLOSE, POWERLINE_ROUND_OPEN, POWERLINE_SEP
|
||||
|
||||
@@ -489,7 +488,7 @@ def test_preview_draws_the_author_and_the_mentions_as_the_transcript_does(powerl
|
||||
mine = ChatMessage(text="yo", outbound=True, is_channel=True, channel_idx=0)
|
||||
assert _preview_text(mine, _NO_KEYS).plain == f"{POWERLINE_ROUND_OPEN} ★ {POWERLINE_SEP} yo"
|
||||
us = ("Me", _OUR_KEY)
|
||||
ours = f"{POWERLINE_ROUND_OPEN} Me {POWERLINE_SEP} ★ yo"
|
||||
ours = f"{POWERLINE_ROUND_OPEN} ★ Me {POWERLINE_SEP} yo"
|
||||
assert _preview_text(mine, _NO_KEYS, us=us).plain == ours
|
||||
named = ChatMessage(text="Bob: hi @[Me]", is_channel=True, channel_idx=0)
|
||||
me = POWERLINE_SEP + " Me " + POWERLINE_ROUND_CLOSE
|
||||
@@ -1222,8 +1221,8 @@ def test_channel_transcript_groups_by_sender() -> None:
|
||||
rendered = _strip_ansi("\n".join(screen._render_grouped(80)))
|
||||
|
||||
assert rendered.count("Alice") == 1 # the two Alice messages share one header
|
||||
# The header of our group is our name, then the ★ (JP, 2026-10-13), not the bare ★.
|
||||
assert "Bob" in rendered and " Me ★" in rendered
|
||||
# The header of our group is our name after the ★ (JP, 2026-10-13), not the bare ★.
|
||||
assert "Bob" in rendered and "★ Me" in rendered
|
||||
assert "hi" in rendered and "again" in rendered # the bodies are there, without the prefix
|
||||
assert "Alice: hi" not in rendered # the raw name prefix moved into the header
|
||||
# Each message keeps its own timestamp on its line, also when grouped under one sender.
|
||||
@@ -1529,7 +1528,7 @@ def test_channel_self_style_keyed_on_concept_not_label() -> None:
|
||||
theirs = ChatMessage(text="you: hi", is_channel=True, channel_idx=0)
|
||||
mine = _channel_screen([], self_name="Me", self_key=_OUR_KEY)
|
||||
turned = f"{node_style(_OUR_KEY)} reverse"
|
||||
assert _ink(mine._group_header("you", ours), " Me ") == turned # our name, turned over
|
||||
assert _ink(mine._group_header("you", ours), " ★ Me ") == turned # our name, turned over
|
||||
screen = _channel_screen([])
|
||||
assert _ink(screen._group_header("you", ours), "★") == "you" # no name: the white star
|
||||
assert _ink(screen._group_header("you", theirs), "you") == "node.unknown" # no key: grey
|
||||
@@ -1550,8 +1549,8 @@ def test_channel_own_messages_do_not_merge_with_remote_namesake() -> None:
|
||||
screen = _channel_screen(messages, self_name="Me", self_key=_OUR_KEY)
|
||||
rendered = _strip_ansi("\n".join(screen._render_grouped(80)))
|
||||
# Two headers, and they are not only apart: theirs is the name that they sent, ours is
|
||||
# our name, then the ★.
|
||||
assert rendered.count("you") == 1 and rendered.count(" Me ★") == 1
|
||||
# our name after the ★.
|
||||
assert rendered.count("you") == 1 and rendered.count("★ Me") == 1
|
||||
|
||||
|
||||
def test_a_blank_line_closes_each_author_where_the_rows_allow(
|
||||
|
||||
+5
-14
@@ -352,7 +352,7 @@ def test_name_chip_draws_us_as_the_star_never_as_our_name(powerline) -> None:
|
||||
|
||||
|
||||
def test_self_chip_is_the_chip_of_our_key_turned_over(powerline) -> None:
|
||||
"""In a chat, our messages go under our name, dark on a light fill of our hue.
|
||||
"""In a chat, our messages go under ``★ Name``, dark on a light fill of our hue.
|
||||
|
||||
The two colours are those of the chip of our key, in the other order. Thus the contrast
|
||||
stays the same, and it is the one light chip among the senders (JP, 2026-10-13).
|
||||
@@ -361,27 +361,18 @@ def test_self_chip_is_the_chip_of_our_key_turned_over(powerline) -> None:
|
||||
ours = self_chip("Me", "5e7f", role=ORIGIN)
|
||||
theirs = name_chip("Me", "5e7f", role=ORIGIN)
|
||||
|
||||
ink, normal = _span_style(ours, "Me"), _span_style(theirs, "Me")
|
||||
assert "★ Me" in ours.plain # the star in the chip, in its dark ink
|
||||
ink, normal = _span_style(ours, "★ Me"), _span_style(theirs, "Me")
|
||||
assert (ink.color.name, ink.bgcolor.name) == (normal.bgcolor.name, normal.color.name)
|
||||
|
||||
|
||||
def test_self_chip_puts_the_star_on_the_page_after_the_chip(powerline) -> None:
|
||||
"""The ``★`` is to the right of our chip, in the yellow of the map (JP, 2026-10-13)."""
|
||||
powerline(True)
|
||||
ours = self_chip("Me", "5e7f", role=ORIGIN)
|
||||
|
||||
assert ours.plain == name_chip("Me", "5e7f", role=ORIGIN).plain + " ★"
|
||||
star = next(s for s in ours.spans if ours.plain[s.start : s.end] == "★")
|
||||
assert str(star.style) == "type.you" # the yellow of the map, on the page
|
||||
|
||||
|
||||
def test_self_chip_is_a_block_in_reverse_video_without_powerline(powerline) -> None:
|
||||
"""With no chips, our name is still dark on the hue of our key, padded as a chip is."""
|
||||
powerline(False)
|
||||
chip = self_chip("Me", "5e7f")
|
||||
|
||||
assert chip.plain == " Me ★"
|
||||
style = _span_style(chip, " Me ")
|
||||
assert chip.plain == " ★ Me "
|
||||
style = _span_style(chip, " ★ Me ")
|
||||
assert style.reverse and style.color.name == node_style("5e7f").removeprefix("bold ")
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user