Suppress pushes for outgoing preview echoes

This commit is contained in:
sevenhill
2026-07-04 22:46:18 +03:00
parent 293937f5d2
commit 0468d02bf3
2 changed files with 225 additions and 2 deletions
@@ -127,13 +127,36 @@ public sealed class MaxBridgeSyncService(
changed++;
}
var previewHint = MessageTextSanitizer.CleanChatPreview(update.LastMessagePreview);
var shouldLoadLastKnownMessage = !chatWasCreated &&
!string.IsNullOrWhiteSpace(previewHint) &&
!string.IsNullOrWhiteSpace(chat.LastMessagePreview) &&
string.Equals(MessageTextSanitizer.CleanChatPreview(chat.LastMessagePreview), previewHint, StringComparison.Ordinal) &&
update.LastMessageIsOutgoing != true &&
update.Messages.Count == 0 &&
HasListClockTime(update.LastMessageTimeText);
List<LastKnownMessageSnapshot> lastKnownMessages = !shouldLoadLastKnownMessage
? []
: await db.Messages
.Where(x =>
x.ChatId == chat.Id &&
x.DeletedAt == null &&
x.Direction == MessageDirection.Outgoing &&
x.Text == previewHint)
.Select(x => new LastKnownMessageSnapshot(x.Direction, x.Text, x.SentAt))
.ToListAsync(cancellationToken);
var lastKnownMessage = lastKnownMessages
.OrderByDescending(x => x.SentAt)
.FirstOrDefault();
if (ApplyListPreview(
update,
chat,
chatWasCreated,
incrementUnread,
sendPushNotifications,
previewPushNotifications))
previewPushNotifications,
lastKnownMessage))
{
changed++;
}
@@ -255,7 +278,8 @@ public sealed class MaxBridgeSyncService(
bool chatWasCreated,
bool incrementUnread,
bool sendPushNotifications,
ICollection<(Chat Chat, Message Message)> previewPushNotifications)
ICollection<(Chat Chat, Message Message)> previewPushNotifications,
LastKnownMessageSnapshot? lastKnownMessage)
{
var preview = MessageTextSanitizer.CleanChatPreview(update.LastMessagePreview);
if (string.IsNullOrWhiteSpace(preview))
@@ -283,8 +307,10 @@ public sealed class MaxBridgeSyncService(
chat.LastMessageAt = previewAt;
chat.UpdatedAt = DateTimeOffset.UtcNow;
var echoesKnownOutgoing = IsKnownOutgoingPreviewEcho(lastKnownMessage, preview, previewAt);
var shouldNotifyCandidate = !chatWasCreated &&
!string.IsNullOrWhiteSpace(previousPreview) &&
!echoesKnownOutgoing &&
update.LastMessageIsOutgoing != true &&
update.Messages.Count == 0 &&
IsFreshListPreview(update, previewAt);
@@ -317,6 +343,31 @@ public sealed class MaxBridgeSyncService(
return true;
}
private static bool IsKnownOutgoingPreviewEcho(
LastKnownMessageSnapshot? lastKnownMessage,
string preview,
DateTimeOffset previewAt)
{
if (lastKnownMessage is null ||
lastKnownMessage.Direction != MessageDirection.Outgoing ||
string.IsNullOrWhiteSpace(lastKnownMessage.Text))
{
return false;
}
var lastText = MessageTextSanitizer.CleanChatPreview(lastKnownMessage.Text);
if (!string.Equals(lastText, preview, StringComparison.Ordinal))
{
return false;
}
var sentAt = lastKnownMessage.SentAt.ToUniversalTime();
var previewUtc = previewAt.ToUniversalTime();
var now = DateTimeOffset.UtcNow;
return Math.Abs((sentAt - previewUtc).TotalMinutes) <= 30 ||
sentAt >= now.AddMinutes(-30);
}
private static bool RememberPreviewNotification(Guid chatId, string preview, DateTimeOffset previewAt)
{
var now = DateTimeOffset.UtcNow;
@@ -755,4 +806,9 @@ public sealed class MaxBridgeSyncService(
_ => null
};
}
private sealed record LastKnownMessageSnapshot(
MessageDirection Direction,
string? Text,
DateTimeOffset SentAt);
}