This commit is contained in:
cake
2025-11-30 15:55:57 +01:00
11 changed files with 458 additions and 54 deletions

View File

@@ -19,3 +19,5 @@ public readonly record struct ChatChannelSnapshot(
bool HasUnread,
int UnreadCount,
IReadOnlyList<ChatMessageEntry> Messages);
public readonly record struct ChatReportResult(bool Success, string? ErrorMessage);

View File

@@ -17,6 +17,8 @@ public sealed class ZoneChatService : DisposableMediatorSubscriberBase, IHostedS
private const int MaxUnreadCount = 999;
private const string ZoneUnavailableMessage = "Zone chat is only available in major cities.";
private const string ZoneChannelKey = "zone";
private const int MaxReportReasonLength = 500;
private const int MaxReportContextLength = 1000;
private readonly ApiController _apiController;
private readonly ChatConfigService _chatConfigService;
@@ -244,6 +246,65 @@ public sealed class ZoneChatService : DisposableMediatorSubscriberBase, IHostedS
public Task<ChatParticipantResolveResultDto?> ResolveParticipantAsync(ChatChannelDescriptor descriptor, string token)
=> _apiController.ResolveChatParticipant(new ChatParticipantResolveRequestDto(descriptor, token));
public Task<ChatReportResult> ReportMessageAsync(ChatChannelDescriptor descriptor, string messageId, string reason, string? additionalContext)
{
if (string.IsNullOrWhiteSpace(messageId))
{
return Task.FromResult(new ChatReportResult(false, "Unable to locate the selected message."));
}
var trimmedReason = reason?.Trim() ?? string.Empty;
if (trimmedReason.Length == 0)
{
return Task.FromResult(new ChatReportResult(false, "Please describe why you are reporting this message."));
}
lock (_sync)
{
if (!_chatEnabled)
{
return Task.FromResult(new ChatReportResult(false, "Enable chat before reporting messages."));
}
if (!_isConnected)
{
return Task.FromResult(new ChatReportResult(false, "Connect to the chat server before reporting messages."));
}
}
if (trimmedReason.Length > MaxReportReasonLength)
{
trimmedReason = trimmedReason[..MaxReportReasonLength];
}
string? context = null;
if (!string.IsNullOrWhiteSpace(additionalContext))
{
context = additionalContext.Trim();
if (context.Length > MaxReportContextLength)
{
context = context[..MaxReportContextLength];
}
}
var normalizedDescriptor = descriptor.WithNormalizedCustomKey();
return ReportMessageInternalAsync(normalizedDescriptor, messageId.Trim(), trimmedReason, context);
}
private async Task<ChatReportResult> ReportMessageInternalAsync(ChatChannelDescriptor descriptor, string messageId, string reason, string? additionalContext)
{
try
{
await _apiController.ReportChatMessage(new ChatReportSubmitDto(descriptor, messageId, reason, additionalContext)).ConfigureAwait(false);
return new ChatReportResult(true, null);
}
catch (Exception ex)
{
Logger.LogWarning(ex, "Failed to submit chat report");
return new ChatReportResult(false, "Failed to submit report. Please try again.");
}
}
public Task StartAsync(CancellationToken cancellationToken)
{
Mediator.Subscribe<DalamudLoginMessage>(this, _ => HandleLogin());