Show director summons as info toasts and presence queue labels.

Corridor waiters need a summon-phase byte on presence (v11); EventDef DirectorSummoned is info-only so clocks keep running.
This commit is contained in:
Leonid Pershin
2026-08-21 13:07:47 +03:00
parent d3c2327e23
commit 9e429d0cd7
29 changed files with 453 additions and 28 deletions
@@ -285,8 +285,10 @@ public class ProtocolCodecTests
Assert.Equal(PresenceState.Here, read.People[0].State);
Assert.Empty(read.People[0].TalkMemberIds);
Assert.Equal("", read.People[0].TalkTopicId);
Assert.Equal(PresenceSummonPhase.None, read.People[0].SummonPhase);
Assert.Equal(PresenceState.Walking, read.People[1].State);
Assert.Empty(read.People[1].TalkMemberIds);
Assert.Equal(PresenceSummonPhase.None, read.People[1].SummonPhase);
}
[Fact]
@@ -313,12 +315,15 @@ public class ProtocolCodecTests
Assert.Equal(0, buffer[offset]);
offset += 1;
offset = AssertWireString(buffer, offset, "");
Assert.Equal(PresenceSummonPhase.None, buffer[offset]);
offset += 1;
Assert.Equal(length, offset);
Assert.Equal(length, ProtocolCodec.PresenceSize(message));
var read = ProtocolCodec.ReadPresence(buffer.AsSpan(0, length));
Assert.Empty(read.People[0].TalkMemberIds);
Assert.Equal("", read.People[0].TalkTopicId);
Assert.Equal(PresenceSummonPhase.None, read.People[0].SummonPhase);
Assert.Equal(message.People[0].Id, read.People[0].Id);
Assert.Equal(message.People[0].NodeId, read.People[0].NodeId);
Assert.Equal(message.People[0].State, read.People[0].State);
@@ -357,16 +362,52 @@ public class ProtocolCodecTests
offset = AssertWireString(buffer, offset, "f0.c0");
offset = AssertWireString(buffer, offset, "f0.c1");
offset = AssertWireString(buffer, offset, "TopicSport");
Assert.Equal(PresenceSummonPhase.None, buffer[offset]);
offset += 1;
Assert.Equal(length, offset);
Assert.Equal(length, ProtocolCodec.PresenceSize(message));
var read = ProtocolCodec.ReadPresence(buffer.AsSpan(0, length));
Assert.Equal(["f0.c0", "f0.c1"], read.People[0].TalkMemberIds);
Assert.Equal("TopicSport", read.People[0].TalkTopicId);
Assert.Equal(PresenceSummonPhase.None, read.People[0].SummonPhase);
Assert.Equal(message.SchoolId, read.SchoolId);
Assert.Equal(message.People[0].Id, read.People[0].Id);
}
[Fact]
public void Presence_SummonPhase_RoundTripsAndMatchesByteLayout()
{
var message = new ServerPresenceMessage(
1,
[],
[new PresencePerson(
"f0.c0",
"corridor-1",
PresenceState.Here,
[],
"",
PresenceSummonPhase.Waiting)]);
var buffer = new byte[ProtocolCodec.PresenceSize(message)];
var length = ProtocolCodec.WritePresence(buffer, message);
var offset = 9;
offset = AssertWireString(buffer, offset, "f0.c0");
offset = AssertWireString(buffer, offset, "corridor-1");
Assert.Equal(PresenceState.Here, buffer[offset]);
offset += 1;
Assert.Equal(0, buffer[offset]);
offset += 1;
offset = AssertWireString(buffer, offset, "");
Assert.Equal(PresenceSummonPhase.Waiting, buffer[offset]);
offset += 1;
Assert.Equal(length, offset);
var read = ProtocolCodec.ReadPresence(buffer.AsSpan(0, length));
Assert.Equal(PresenceSummonPhase.Waiting, Assert.Single(read.People).SummonPhase);
}
[Fact]
public void Presence_DoesNotContainPersonDisplayName()
{