✨ Direct messages
This commit is contained in:
parent
d0a92bc8b3
commit
573f984e2c
@ -43,7 +43,7 @@ public partial class ChatController(AppDatabase db, ChatService cs) : Controller
|
||||
var member = await db.ChatMembers
|
||||
.Where(m => m.AccountId == currentUser.Id && m.ChatRoomId == roomId)
|
||||
.FirstOrDefaultAsync();
|
||||
if (member == null || member.Role < ChatMemberRole.Normal)
|
||||
if (member == null || member.Role < ChatMemberRole.Member)
|
||||
return StatusCode(403, "You are not a member of this chat room.");
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ public partial class ChatController(AppDatabase db, ChatService cs) : Controller
|
||||
var member = await db.ChatMembers
|
||||
.Where(m => m.AccountId == currentUser.Id && m.ChatRoomId == roomId)
|
||||
.FirstOrDefaultAsync();
|
||||
if (member == null || member.Role < ChatMemberRole.Normal)
|
||||
if (member == null || member.Role < ChatMemberRole.Member)
|
||||
return StatusCode(403, "You are not a member of this chat room.");
|
||||
}
|
||||
|
||||
@ -118,7 +118,7 @@ public partial class ChatController(AppDatabase db, ChatService cs) : Controller
|
||||
.Include(m => m.Account)
|
||||
.Include(m => m.Account.Profile)
|
||||
.FirstOrDefaultAsync();
|
||||
if (member == null || member.Role < ChatMemberRole.Normal) return StatusCode(403, "You need to be a normal member to send messages here.");
|
||||
if (member == null || member.Role < ChatMemberRole.Member) return StatusCode(403, "You need to be a normal member to send messages here.");
|
||||
|
||||
var message = new Message
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ public enum ChatMemberRole
|
||||
{
|
||||
Owner = 100,
|
||||
Moderator = 50,
|
||||
Normal = 0
|
||||
Member = 0
|
||||
}
|
||||
|
||||
public enum ChatMemberNotify
|
||||
@ -54,7 +54,7 @@ public class ChatMember : ModelBase
|
||||
|
||||
[MaxLength(1024)] public string? Nick { get; set; }
|
||||
|
||||
public ChatMemberRole Role { get; set; } = ChatMemberRole.Normal;
|
||||
public ChatMemberRole Role { get; set; } = ChatMemberRole.Member;
|
||||
public ChatMemberNotify Notify { get; set; } = ChatMemberNotify.All;
|
||||
public Instant? JoinedAt { get; set; }
|
||||
public bool IsBot { get; set; } = false;
|
||||
|
@ -26,19 +26,102 @@ public class ChatRoomController(AppDatabase db, FileService fs, ChatRoomService
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<List<ChatRoom>>> ListJoinedChatRooms()
|
||||
{
|
||||
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
|
||||
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser)
|
||||
return Unauthorized();
|
||||
|
||||
var userId = currentUser.Id;
|
||||
|
||||
var members = await db.ChatMembers
|
||||
var chatRooms = await db.ChatMembers
|
||||
.Where(m => m.AccountId == userId)
|
||||
.Where(m => m.JoinedAt != null)
|
||||
.Include(e => e.ChatRoom)
|
||||
.Include(m => m.ChatRoom)
|
||||
.Select(m => m.ChatRoom)
|
||||
.ToListAsync();
|
||||
|
||||
return members.ToList();
|
||||
var directRoomsId = chatRooms
|
||||
.Where(r => r.Type == ChatRoomType.DirectMessage)
|
||||
.Select(r => r.Id)
|
||||
.ToList();
|
||||
var directMembers = directRoomsId.Count != 0
|
||||
? await db.ChatMembers
|
||||
.Where(m => directRoomsId.Contains(m.ChatRoomId))
|
||||
.Where(m => m.AccountId != userId)
|
||||
.Include(m => m.Account)
|
||||
.Include(m => m.Account.Profile)
|
||||
.ToDictionaryAsync(m => m.ChatRoomId, m => m)
|
||||
: new Dictionary<long, ChatMember>();
|
||||
|
||||
// Map the results
|
||||
var result = chatRooms.Select(r =>
|
||||
{
|
||||
if (r.Type == ChatRoomType.DirectMessage && directMembers.TryGetValue(r.Id, out var otherMember))
|
||||
r.Members = new List<ChatMember> { otherMember };
|
||||
return r;
|
||||
}).ToList();
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
public class DmCreationRequest
|
||||
{
|
||||
[Required] public long RelatedUserId { get; set; }
|
||||
}
|
||||
|
||||
[HttpPost("direct")]
|
||||
[Authorize]
|
||||
public async Task<ActionResult<ChatRoom>> CreateDirectMessage([FromBody] DmCreationRequest request)
|
||||
{
|
||||
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser)
|
||||
return Unauthorized();
|
||||
|
||||
var relatedUser = await db.Accounts.FindAsync(request.RelatedUserId);
|
||||
if (relatedUser is null)
|
||||
return BadRequest("Related user was not found");
|
||||
|
||||
// Check if DM already exists between these users
|
||||
var existingDm = await db.ChatRooms
|
||||
.Include(c => c.Members)
|
||||
.Where(c => c.Type == ChatRoomType.DirectMessage && c.Members.Count == 2)
|
||||
.Where(c => c.Members.Any(m => m.AccountId == currentUser.Id))
|
||||
.Where(c => c.Members.Any(m => m.AccountId == request.RelatedUserId))
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (existingDm != null)
|
||||
return Ok(existingDm); // Return existing DM if found
|
||||
|
||||
// Create new DM chat room
|
||||
var dmRoom = new ChatRoom
|
||||
{
|
||||
Name = $"DM between #{currentUser.Id} and #{request.RelatedUserId}",
|
||||
Type = ChatRoomType.DirectMessage,
|
||||
IsPublic = false,
|
||||
Members = new List<ChatMember>
|
||||
{
|
||||
new()
|
||||
{
|
||||
AccountId = currentUser.Id,
|
||||
Role = ChatMemberRole.Owner,
|
||||
JoinedAt = NodaTime.Instant.FromDateTimeUtc(DateTime.UtcNow)
|
||||
},
|
||||
new()
|
||||
{
|
||||
AccountId = request.RelatedUserId,
|
||||
Role = ChatMemberRole.Member,
|
||||
JoinedAt = null, // Pending status
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
db.ChatRooms.Add(dmRoom);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
var invitedMember = dmRoom.Members.First(m => m.AccountId == request.RelatedUserId);
|
||||
await crs.SendInviteNotify(invitedMember);
|
||||
|
||||
return Ok(dmRoom);
|
||||
}
|
||||
|
||||
|
||||
public class ChatRoomRequest
|
||||
{
|
||||
[Required] [MaxLength(1024)] public string? Name { get; set; }
|
||||
@ -60,6 +143,7 @@ public class ChatRoomController(AppDatabase db, FileService fs, ChatRoomService
|
||||
{
|
||||
Name = request.Name,
|
||||
Description = request.Description ?? string.Empty,
|
||||
Type = ChatRoomType.Group,
|
||||
Members = new List<ChatMember>
|
||||
{
|
||||
new()
|
||||
@ -106,6 +190,7 @@ public class ChatRoomController(AppDatabase db, FileService fs, ChatRoomService
|
||||
return Ok(chatRoom);
|
||||
}
|
||||
|
||||
|
||||
[HttpPatch("{id:long}")]
|
||||
public async Task<ActionResult<ChatRoom>> UpdateChatRoom(long id, [FromBody] ChatRoomRequest request)
|
||||
{
|
||||
@ -395,7 +480,7 @@ public class ChatRoomController(AppDatabase db, FileService fs, ChatRoomService
|
||||
|
||||
[HttpPatch("{roomId:long}/members/{memberId:long}/role")]
|
||||
[Authorize]
|
||||
public async Task<ActionResult<ChatMember>> UpdateChatMemberRole(long roomId, long memberId,
|
||||
public async Task<ActionResult<ChatMember>> UpdateChatMemberRole(long roomId, long memberId,
|
||||
[FromBody] ChatMemberRequest request)
|
||||
{
|
||||
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
|
||||
@ -515,7 +600,7 @@ public class ChatRoomController(AppDatabase db, FileService fs, ChatRoomService
|
||||
.Where(m => m.Role == ChatMemberRole.Owner)
|
||||
.Where(m => m.AccountId != currentUser.Id)
|
||||
.AnyAsync();
|
||||
|
||||
|
||||
if (!otherOwners)
|
||||
return BadRequest("The last owner cannot leave the chat. Transfer ownership first or delete the chat.");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user