adjust visibility flags, improve chat functionality, bump submodules
This commit is contained in:
@@ -3,10 +3,21 @@ using LightlessSync.API.Dto.Chat;
|
||||
namespace LightlessSync.Services.Chat;
|
||||
|
||||
public sealed record ChatMessageEntry(
|
||||
ChatMessageDto Payload,
|
||||
ChatMessageDto? Payload,
|
||||
string DisplayName,
|
||||
bool FromSelf,
|
||||
DateTime ReceivedAtUtc);
|
||||
DateTime ReceivedAtUtc,
|
||||
ChatSystemEntry? SystemMessage = null)
|
||||
{
|
||||
public bool IsSystem => SystemMessage is not null;
|
||||
}
|
||||
|
||||
public enum ChatSystemEntryType
|
||||
{
|
||||
ZoneSeparator
|
||||
}
|
||||
|
||||
public sealed record ChatSystemEntry(ChatSystemEntryType Type, string? ZoneName);
|
||||
|
||||
public readonly record struct ChatChannelSnapshot(
|
||||
string Key,
|
||||
|
||||
@@ -240,8 +240,22 @@ public sealed class ZoneChatService : DisposableMediatorSubscriberBase, IHostedS
|
||||
}
|
||||
}
|
||||
|
||||
public Task<ChatParticipantResolveResultDto?> ResolveParticipantAsync(ChatChannelDescriptor descriptor, string token)
|
||||
=> _apiController.ResolveChatParticipant(new ChatParticipantResolveRequestDto(descriptor, token));
|
||||
public async Task<bool> SetParticipantMuteAsync(ChatChannelDescriptor descriptor, string token, bool mute)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(token))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
await _apiController.SetChatParticipantMute(new ChatParticipantMuteRequestDto(descriptor, token, mute)).ConfigureAwait(false);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogWarning(ex, "Failed to update chat participant mute state");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Task<ChatReportResult> ReportMessageAsync(ChatChannelDescriptor descriptor, string messageId, string reason, string? additionalContext)
|
||||
{
|
||||
@@ -534,6 +548,7 @@ public sealed class ZoneChatService : DisposableMediatorSubscriberBase, IHostedS
|
||||
}
|
||||
|
||||
bool shouldForceSend;
|
||||
ChatMessageEntry? zoneSeparatorEntry = null;
|
||||
|
||||
using (_sync.EnterScope())
|
||||
{
|
||||
@@ -544,11 +559,24 @@ public sealed class ZoneChatService : DisposableMediatorSubscriberBase, IHostedS
|
||||
state.IsAvailable = _chatEnabled;
|
||||
state.StatusText = _chatEnabled ? null : "Chat services disabled";
|
||||
|
||||
var previousDescriptor = _lastZoneDescriptor;
|
||||
var zoneChanged = previousDescriptor.HasValue && !ChannelDescriptorsMatch(previousDescriptor.Value, descriptor.Value);
|
||||
|
||||
_activeChannelKey = ZoneChannelKey;
|
||||
shouldForceSend = force || !_lastZoneDescriptor.HasValue || !ChannelDescriptorsMatch(_lastZoneDescriptor.Value, descriptor.Value);
|
||||
shouldForceSend = force || !previousDescriptor.HasValue || zoneChanged;
|
||||
if (zoneChanged && state.Messages.Any(m => !m.IsSystem))
|
||||
{
|
||||
zoneSeparatorEntry = AddZoneSeparatorLocked(state, definition.Value.DisplayName);
|
||||
}
|
||||
|
||||
_lastZoneDescriptor = descriptor;
|
||||
}
|
||||
|
||||
if (zoneSeparatorEntry is not null)
|
||||
{
|
||||
Mediator.Publish(new ChatChannelMessageAdded(ZoneChannelKey, zoneSeparatorEntry));
|
||||
}
|
||||
|
||||
PublishChannelListChanged();
|
||||
await SendPresenceAsync(descriptor.Value, territoryId, isActive: true, force: shouldForceSend).ConfigureAwait(false);
|
||||
}
|
||||
@@ -561,7 +589,6 @@ public sealed class ZoneChatService : DisposableMediatorSubscriberBase, IHostedS
|
||||
private async Task LeaveCurrentZoneAsync(bool force, ushort territoryId)
|
||||
{
|
||||
ChatChannelDescriptor? descriptor = null;
|
||||
bool clearedHistory = false;
|
||||
|
||||
using (_sync.EnterScope())
|
||||
{
|
||||
@@ -570,15 +597,6 @@ public sealed class ZoneChatService : DisposableMediatorSubscriberBase, IHostedS
|
||||
|
||||
if (_channels.TryGetValue(ZoneChannelKey, out var state))
|
||||
{
|
||||
if (state.Messages.Count > 0)
|
||||
{
|
||||
state.Messages.Clear();
|
||||
state.HasUnread = false;
|
||||
state.UnreadCount = 0;
|
||||
_lastReadCounts[ZoneChannelKey] = 0;
|
||||
clearedHistory = true;
|
||||
}
|
||||
|
||||
state.IsConnected = _isConnected;
|
||||
state.IsAvailable = false;
|
||||
state.StatusText = !_chatEnabled
|
||||
@@ -593,11 +611,6 @@ public sealed class ZoneChatService : DisposableMediatorSubscriberBase, IHostedS
|
||||
}
|
||||
}
|
||||
|
||||
if (clearedHistory)
|
||||
{
|
||||
PublishHistoryCleared(ZoneChannelKey);
|
||||
}
|
||||
|
||||
PublishChannelListChanged();
|
||||
|
||||
if (descriptor.HasValue)
|
||||
@@ -1007,6 +1020,39 @@ public sealed class ZoneChatService : DisposableMediatorSubscriberBase, IHostedS
|
||||
return new ChatMessageEntry(dto, displayName, fromSelf, DateTime.UtcNow);
|
||||
}
|
||||
|
||||
private ChatMessageEntry AddZoneSeparatorLocked(ChatChannelState state, string zoneDisplayName)
|
||||
{
|
||||
var separator = new ChatMessageEntry(
|
||||
null,
|
||||
string.Empty,
|
||||
false,
|
||||
DateTime.UtcNow,
|
||||
new ChatSystemEntry(ChatSystemEntryType.ZoneSeparator, zoneDisplayName));
|
||||
|
||||
state.Messages.Add(separator);
|
||||
if (state.Messages.Count > MaxMessageHistory)
|
||||
{
|
||||
state.Messages.RemoveAt(0);
|
||||
}
|
||||
|
||||
if (string.Equals(_activeChannelKey, ZoneChannelKey, StringComparison.Ordinal))
|
||||
{
|
||||
state.HasUnread = false;
|
||||
state.UnreadCount = 0;
|
||||
_lastReadCounts[ZoneChannelKey] = state.Messages.Count;
|
||||
}
|
||||
else if (_lastReadCounts.TryGetValue(ZoneChannelKey, out var readCount))
|
||||
{
|
||||
_lastReadCounts[ZoneChannelKey] = readCount + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_lastReadCounts[ZoneChannelKey] = state.Messages.Count;
|
||||
}
|
||||
|
||||
return separator;
|
||||
}
|
||||
|
||||
private string ResolveDisplayName(ChatMessageDto dto, bool fromSelf)
|
||||
{
|
||||
var isZone = dto.Channel.Type == ChatChannelType.Zone;
|
||||
@@ -1070,8 +1116,6 @@ public sealed class ZoneChatService : DisposableMediatorSubscriberBase, IHostedS
|
||||
|
||||
private void PublishChannelListChanged() => Mediator.Publish(new ChatChannelsUpdated());
|
||||
|
||||
private void PublishHistoryCleared(string channelKey) => Mediator.Publish(new ChatChannelHistoryCleared(channelKey));
|
||||
|
||||
private static IEnumerable<string> EnumerateTerritoryKeys(string? value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
|
||||
Reference in New Issue
Block a user