⚡ Better cloud file allocation and free in chat
This commit is contained in:
parent
2778626b1f
commit
5f69d8ac80
@ -229,27 +229,22 @@ public partial class ChatController(AppDatabase db, ChatService cs, FileService
|
|||||||
var message = await db.ChatMessages
|
var message = await db.ChatMessages
|
||||||
.Include(m => m.Sender)
|
.Include(m => m.Sender)
|
||||||
.Include(m => m.Sender.Account)
|
.Include(m => m.Sender.Account)
|
||||||
.Include(m => m.Sender.Account.Profile).Include(message => message.Attachments)
|
.Include(m => m.Sender.Account.Profile)
|
||||||
|
.Include(message => message.Attachments)
|
||||||
.Include(message => message.ChatRoom)
|
.Include(message => message.ChatRoom)
|
||||||
.FirstOrDefaultAsync(m => m.Id == messageId && m.ChatRoomId == roomId);
|
.FirstOrDefaultAsync(m => m.Id == messageId && m.ChatRoomId == roomId);
|
||||||
|
|
||||||
if (message == null) return NotFound();
|
if (message == null) return NotFound();
|
||||||
|
|
||||||
if (message.Sender.AccountId != currentUser.Id)
|
if (message.Sender.AccountId != currentUser.Id)
|
||||||
return StatusCode(403, "You can only edit your own messages.");
|
return StatusCode(403, "You can only edit your own messages.");
|
||||||
|
|
||||||
if (request.Content is not null)
|
|
||||||
message.Content = request.Content;
|
|
||||||
if (request.Meta is not null)
|
|
||||||
message.Meta = request.Meta;
|
|
||||||
|
|
||||||
if (request.RepliedMessageId.HasValue)
|
if (request.RepliedMessageId.HasValue)
|
||||||
{
|
{
|
||||||
var repliedMessage = await db.ChatMessages
|
var repliedMessage = await db.ChatMessages
|
||||||
.FirstOrDefaultAsync(m => m.Id == request.RepliedMessageId.Value && m.ChatRoomId == roomId);
|
.FirstOrDefaultAsync(m => m.Id == request.RepliedMessageId.Value && m.ChatRoomId == roomId);
|
||||||
if (repliedMessage == null)
|
if (repliedMessage == null)
|
||||||
return BadRequest("The message you're replying to does not exist.");
|
return BadRequest("The message you're replying to does not exist.");
|
||||||
|
|
||||||
message.RepliedMessageId = repliedMessage.Id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.ForwardedMessageId.HasValue)
|
if (request.ForwardedMessageId.HasValue)
|
||||||
@ -258,24 +253,16 @@ public partial class ChatController(AppDatabase db, ChatService cs, FileService
|
|||||||
.FirstOrDefaultAsync(m => m.Id == request.ForwardedMessageId.Value);
|
.FirstOrDefaultAsync(m => m.Id == request.ForwardedMessageId.Value);
|
||||||
if (forwardedMessage == null)
|
if (forwardedMessage == null)
|
||||||
return BadRequest("The message you're forwarding does not exist.");
|
return BadRequest("The message you're forwarding does not exist.");
|
||||||
|
|
||||||
message.ForwardedMessageId = forwardedMessage.Id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.AttachmentsId is not null)
|
// Call service method to update the message
|
||||||
{
|
await cs.UpdateMessageAsync(
|
||||||
message.Attachments = (await fs.DiffAndMarkFilesAsync(request.AttachmentsId, message.Attachments)).current;
|
message,
|
||||||
await fs.DiffAndSetExpiresAsync(request.AttachmentsId, Duration.FromDays(30), message.Attachments);
|
request.Meta,
|
||||||
}
|
request.Content,
|
||||||
|
request.RepliedMessageId,
|
||||||
message.EditedAt = SystemClock.Instance.GetCurrentInstant();
|
request.ForwardedMessageId,
|
||||||
db.Update(message);
|
request.AttachmentsId
|
||||||
await db.SaveChangesAsync();
|
|
||||||
_ = cs.DeliverMessageAsync(
|
|
||||||
message,
|
|
||||||
message.Sender,
|
|
||||||
message.ChatRoom,
|
|
||||||
WebSocketPacketType.MessageUpdate
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return Ok(message);
|
return Ok(message);
|
||||||
@ -290,20 +277,16 @@ public partial class ChatController(AppDatabase db, ChatService cs, FileService
|
|||||||
var message = await db.ChatMessages
|
var message = await db.ChatMessages
|
||||||
.Include(m => m.Sender)
|
.Include(m => m.Sender)
|
||||||
.Include(m => m.ChatRoom)
|
.Include(m => m.ChatRoom)
|
||||||
|
.Include(m => m.Attachments)
|
||||||
.FirstOrDefaultAsync(m => m.Id == messageId && m.ChatRoomId == roomId);
|
.FirstOrDefaultAsync(m => m.Id == messageId && m.ChatRoomId == roomId);
|
||||||
|
|
||||||
if (message == null) return NotFound();
|
if (message == null) return NotFound();
|
||||||
|
|
||||||
if (message.Sender.AccountId != currentUser.Id)
|
if (message.Sender.AccountId != currentUser.Id)
|
||||||
return StatusCode(403, "You can only delete your own messages.");
|
return StatusCode(403, "You can only delete your own messages.");
|
||||||
|
|
||||||
db.ChatMessages.Remove(message);
|
// Call service method to delete the message
|
||||||
await db.SaveChangesAsync();
|
await cs.DeleteMessageAsync(message);
|
||||||
_ = cs.DeliverMessageAsync(
|
|
||||||
message,
|
|
||||||
message.Sender,
|
|
||||||
message.ChatRoom,
|
|
||||||
WebSocketPacketType.MessageDelete
|
|
||||||
);
|
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ public class ChatService(
|
|||||||
IRealtimeService realtime
|
IRealtimeService realtime
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
private const string ChatFileUsageIdentifier = "chat";
|
||||||
|
|
||||||
public async Task<Message> SendMessageAsync(Message message, ChatMember sender, ChatRoom room)
|
public async Task<Message> SendMessageAsync(Message message, ChatMember sender, ChatRoom room)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(message.Nonce)) message.Nonce = Guid.NewGuid().ToString();
|
if (string.IsNullOrWhiteSpace(message.Nonce)) message.Nonce = Guid.NewGuid().ToString();
|
||||||
@ -29,12 +31,11 @@ public class ChatService(
|
|||||||
{
|
{
|
||||||
await fs.MarkUsageRangeAsync(files, 1);
|
await fs.MarkUsageRangeAsync(files, 1);
|
||||||
await fs.SetExpiresRangeAsync(files, Duration.FromDays(30));
|
await fs.SetExpiresRangeAsync(files, Duration.FromDays(30));
|
||||||
|
await fs.SetUsageRangeAsync(files, ChatFileUsageIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then start the delivery process
|
// Then start the delivery process
|
||||||
// Using ConfigureAwait(false) is correct here since we don't need context to flow
|
_ = Task.Run(() => DeliverMessageAsync(message, sender, room));
|
||||||
_ = Task.Run(() => DeliverMessageAsync(message, sender, room))
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
@ -276,6 +277,69 @@ public class ChatService(
|
|||||||
CurrentTimestamp = SystemClock.Instance.GetCurrentInstant()
|
CurrentTimestamp = SystemClock.Instance.GetCurrentInstant()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<Message> UpdateMessageAsync(
|
||||||
|
Message message,
|
||||||
|
Dictionary<string, object>? meta = null,
|
||||||
|
string? content = null,
|
||||||
|
Guid? repliedMessageId = null,
|
||||||
|
Guid? forwardedMessageId = null,
|
||||||
|
List<string>? attachmentsId = null
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (content is not null)
|
||||||
|
message.Content = content;
|
||||||
|
|
||||||
|
if (meta is not null)
|
||||||
|
message.Meta = meta;
|
||||||
|
|
||||||
|
if (repliedMessageId.HasValue)
|
||||||
|
message.RepliedMessageId = repliedMessageId;
|
||||||
|
|
||||||
|
if (forwardedMessageId.HasValue)
|
||||||
|
message.ForwardedMessageId = forwardedMessageId;
|
||||||
|
|
||||||
|
if (attachmentsId is not null)
|
||||||
|
{
|
||||||
|
message.Attachments = (await fs.DiffAndMarkFilesAsync(attachmentsId, message.Attachments)).current;
|
||||||
|
await fs.DiffAndSetExpiresAsync(attachmentsId, Duration.FromDays(30), message.Attachments);
|
||||||
|
await fs.DiffAndSetUsageAsync(attachmentsId, ChatFileUsageIdentifier, message.Attachments);
|
||||||
|
}
|
||||||
|
|
||||||
|
message.EditedAt = SystemClock.Instance.GetCurrentInstant();
|
||||||
|
db.Update(message);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
|
_ = DeliverMessageAsync(
|
||||||
|
message,
|
||||||
|
message.Sender,
|
||||||
|
message.ChatRoom,
|
||||||
|
WebSocketPacketType.MessageUpdate
|
||||||
|
);
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deletes a message and notifies other chat members
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to delete</param>
|
||||||
|
public async Task DeleteMessageAsync(Message message)
|
||||||
|
{
|
||||||
|
var files = message.Attachments.Distinct().ToList();
|
||||||
|
if (files.Count != 0)
|
||||||
|
await fs.MarkUsageRangeAsync(files, -1);
|
||||||
|
|
||||||
|
db.ChatMessages.Remove(message);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
|
_ = DeliverMessageAsync(
|
||||||
|
message,
|
||||||
|
message.Sender,
|
||||||
|
message.ChatRoom,
|
||||||
|
WebSocketPacketType.MessageDelete
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MessageChangeAction
|
public class MessageChangeAction
|
||||||
|
Loading…
x
Reference in New Issue
Block a user