Удаление сообщений
This commit is contained in:
@@ -32,7 +32,8 @@ public record MessageDetailDto(
|
|||||||
bool? PollIsMultipleChoice = null,
|
bool? PollIsMultipleChoice = null,
|
||||||
bool? PollIsAnonymous = null,
|
bool? PollIsAnonymous = null,
|
||||||
bool? PollIsClosed = null,
|
bool? PollIsClosed = null,
|
||||||
List<Guid>? UserVotedOptionIds = null
|
List<Guid>? UserVotedOptionIds = null,
|
||||||
|
bool IsDeletedForUser = false
|
||||||
);
|
);
|
||||||
|
|
||||||
public record ReplyToMessageDto(
|
public record ReplyToMessageDto(
|
||||||
|
|||||||
+12
-17
@@ -42,10 +42,16 @@ public sealed class DeleteMessagesCommandHandler : ICommandHandler<DeleteMessage
|
|||||||
|
|
||||||
if (request.DeleteForAll)
|
if (request.DeleteForAll)
|
||||||
{
|
{
|
||||||
|
// Only message sender can delete for everyone
|
||||||
if (message.SenderId == request.UserId)
|
if (message.SenderId == request.UserId)
|
||||||
{
|
{
|
||||||
message.Delete();
|
message.Delete();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If not the sender, just delete for current user
|
||||||
|
message.DeleteForUser(request.UserId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -55,24 +61,13 @@ public sealed class DeleteMessagesCommandHandler : ICommandHandler<DeleteMessage
|
|||||||
await _messageRepository.UpdateAsync(message, cancellationToken);
|
await _messageRepository.UpdateAsync(message, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.DeleteForAll)
|
// Notify all clients in the chat about the deletion
|
||||||
|
await _hubContext.Clients.Group(request.ChatId.ToString()).SendAsync("messages_deleted", new
|
||||||
{
|
{
|
||||||
await _hubContext.Clients.Group(request.ChatId.ToString()).SendAsync("messages_deleted", new
|
chatId = request.ChatId,
|
||||||
{
|
messageIds = request.MessageIds,
|
||||||
chatId = request.ChatId,
|
deleteForAll = request.DeleteForAll
|
||||||
messageIds = request.MessageIds,
|
});
|
||||||
deleteForAll = true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await _hubContext.Clients.User(request.UserId.ToString()).SendAsync("messages_deleted", new
|
|
||||||
{
|
|
||||||
chatId = request.ChatId,
|
|
||||||
messageIds = request.MessageIds,
|
|
||||||
deleteForAll = false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return global::Knot.Shared.Kernel.Result.Success();
|
return global::Knot.Shared.Kernel.Result.Success();
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-9
@@ -3,11 +3,11 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Knot.Contracts.Conversations.Application.Abstractions;
|
||||||
|
using Knot.Contracts.Conversations.Domain;
|
||||||
using Knot.Contracts.Messaging.Application.Abstractions;
|
using Knot.Contracts.Messaging.Application.Abstractions;
|
||||||
using Knot.Contracts.Messaging.Domain;
|
using Knot.Contracts.Messaging.Domain;
|
||||||
using Knot.Contracts.Conversations.Application.Abstractions;
|
|
||||||
using Knot.Modules.Conversations.Application.DTOs;
|
using Knot.Modules.Conversations.Application.DTOs;
|
||||||
using Knot.Contracts.Conversations.Domain;
|
|
||||||
using Knot.Shared.Kernel;
|
using Knot.Shared.Kernel;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
|
|
||||||
@@ -115,6 +115,7 @@ internal sealed class GetMessagesQueryHandler : IQueryHandler<GetMessagesQuery,
|
|||||||
senders.TryGetValue(message.SenderId, out var sender);
|
senders.TryGetValue(message.SenderId, out var sender);
|
||||||
reactionsByMessage.TryGetValue(message.Id, out var reactions);
|
reactionsByMessage.TryGetValue(message.Id, out var reactions);
|
||||||
|
|
||||||
|
|
||||||
Message? replyMsg = null;
|
Message? replyMsg = null;
|
||||||
if (message.ReplyToId.HasValue)
|
if (message.ReplyToId.HasValue)
|
||||||
{
|
{
|
||||||
@@ -141,7 +142,7 @@ internal sealed class GetMessagesQueryHandler : IQueryHandler<GetMessagesQuery,
|
|||||||
replyMsg is MediaMessage mm ? mm.Media.Select(m => new MediaDto(m.Id, m.Type, m.Url, m.Filename, m.Size, m.Duration)).ToList() : new List<MediaDto>(),
|
replyMsg is MediaMessage mm ? mm.Media.Select(m => new MediaDto(m.Id, m.Type, m.Url, m.Filename, m.Size, m.Duration)).ToList() : new List<MediaDto>(),
|
||||||
replySender != null ? new MessageSenderDto(replySender.Id, replySender.Username, replySender.DisplayName, replySender.Avatar) : null
|
replySender != null ? new MessageSenderDto(replySender.Id, replySender.Username, replySender.DisplayName, replySender.Avatar) : null
|
||||||
) : null,
|
) : null,
|
||||||
message is TextMessage tm ? tm.Quote : null,
|
(message as TextMessage)?.Quote,
|
||||||
message.IsEdited,
|
message.IsEdited,
|
||||||
message.IsDeleted,
|
message.IsDeleted,
|
||||||
message.CreatedAt,
|
message.CreatedAt,
|
||||||
@@ -154,19 +155,22 @@ internal sealed class GetMessagesQueryHandler : IQueryHandler<GetMessagesQuery,
|
|||||||
(message as MediaMessage)?.Media.Select(m => new MediaDto(m.Id, m.Type, m.Url, m.Filename, m.Size, m.Duration)).ToList() ?? new List<MediaDto>(),
|
(message as MediaMessage)?.Media.Select(m => new MediaDto(m.Id, m.Type, m.Url, m.Filename, m.Size, m.Duration)).ToList() ?? new List<MediaDto>(),
|
||||||
sender != null ? new MessageSenderDto(sender.Id, sender.Username, sender.DisplayName, sender.Avatar) : new MessageSenderDto(message.SenderId, "unknown", "Unknown", null),
|
sender != null ? new MessageSenderDto(sender.Id, sender.Username, sender.DisplayName, sender.Avatar) : new MessageSenderDto(message.SenderId, "unknown", "Unknown", null),
|
||||||
new List<ReadByDto>(), // ReadBy not implemented in this detailed view yet
|
new List<ReadByDto>(), // ReadBy not implemented in this detailed view yet
|
||||||
reactions?.Select(r => {
|
reactions?.Select(r =>
|
||||||
|
{
|
||||||
senders.TryGetValue(r.UserId, out var ru);
|
senders.TryGetValue(r.UserId, out var ru);
|
||||||
return new MessageReactionDto(r.Id, r.Emoji, r.UserId, ru != null ? new MessageSenderDto(ru.Id, ru.Username, ru.DisplayName, ru.Avatar) : null);
|
return new MessageReactionDto(r.Id, r.Emoji, r.UserId, ru != null ? new MessageSenderDto(ru.Id, ru.Username, ru.DisplayName, ru.Avatar) : null);
|
||||||
}).ToList() ?? new List<MessageReactionDto>(),
|
}).ToList() ?? new List<MessageReactionDto>(),
|
||||||
(message as CallMessage)?.CallType,
|
(message as CallMessage)?.CallType,
|
||||||
(message as CallMessage)?.CallStatus,
|
(message as CallMessage)?.CallStatus,
|
||||||
(message as CallMessage)?.Duration,
|
(message as CallMessage)?.Duration,
|
||||||
(message as PollMessage)?.Options.Select(o => {
|
(message as PollMessage)?.Options.Select(o =>
|
||||||
|
{
|
||||||
var pm = (PollMessage)message;
|
var pm = (PollMessage)message;
|
||||||
var voters = pm.IsAnonymous == false
|
var voters = pm.IsAnonymous == false
|
||||||
? pm.Votes
|
? pm.Votes
|
||||||
.Where(v => v.OptionId == o.Id)
|
.Where(v => v.OptionId == o.Id)
|
||||||
.Select(v => {
|
.Select(v =>
|
||||||
|
{
|
||||||
senders.TryGetValue(v.UserId, out var vu);
|
senders.TryGetValue(v.UserId, out var vu);
|
||||||
return vu != null
|
return vu != null
|
||||||
? new MessageSenderDto(vu.Id, vu.Username, vu.DisplayName, vu.Avatar)
|
? new MessageSenderDto(vu.Id, vu.Username, vu.DisplayName, vu.Avatar)
|
||||||
@@ -174,12 +178,13 @@ internal sealed class GetMessagesQueryHandler : IQueryHandler<GetMessagesQuery,
|
|||||||
})
|
})
|
||||||
.ToList()
|
.ToList()
|
||||||
: null;
|
: null;
|
||||||
return new PollOptionDto(o.Id, o.Text, o.VoteCount, voters, pm.IsAnonymous == false ? pm.Votes.Where(v => v.OptionId == o.Id).Select(v => v.UserId).ToList() : null);
|
return new PollOptionDto(o.Id, o.Text, o.VoteCount, voters, pm.IsAnonymous == false ? pm.Votes.Where(v => v.OptionId == o.Id).Select(v => v.UserId).ToList() : null);
|
||||||
}).ToList(),
|
}).ToList(),
|
||||||
(message as PollMessage)?.IsMultipleChoice,
|
(message as PollMessage)?.IsMultipleChoice,
|
||||||
(message as PollMessage)?.IsAnonymous,
|
(message as PollMessage)?.IsAnonymous,
|
||||||
(message as PollMessage)?.IsClosed,
|
(message as PollMessage)?.IsClosed,
|
||||||
(message as PollMessage)?.Votes.Where(v => v.UserId == request.UserId).Select(v => v.OptionId).ToList()
|
(message as PollMessage)?.Votes.Where(v => v.UserId == request.UserId).Select(v => v.OptionId).ToList(),
|
||||||
|
message.IsDeletedForUser(request.UserId)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ export interface Message {
|
|||||||
storyMediaType?: string | null;
|
storyMediaType?: string | null;
|
||||||
isEdited: boolean;
|
isEdited: boolean;
|
||||||
isDeleted: boolean;
|
isDeleted: boolean;
|
||||||
|
isDeletedForUser?: boolean;
|
||||||
scheduledAt?: string | null;
|
scheduledAt?: string | null;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
updatedAt?: string;
|
updatedAt?: string;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user