♻️ Still don't know what I am doing
This commit is contained in:
@@ -20,31 +20,6 @@ public class WebSocketService
|
||||
|
||||
private static readonly ConcurrentDictionary<string, string> ActiveSubscriptions = new(); // deviceId -> chatRoomId
|
||||
|
||||
public void SubscribeToChatRoom(string chatRoomId, string deviceId)
|
||||
{
|
||||
ActiveSubscriptions[deviceId] = chatRoomId;
|
||||
}
|
||||
|
||||
public void UnsubscribeFromChatRoom(string deviceId)
|
||||
{
|
||||
ActiveSubscriptions.TryRemove(deviceId, out _);
|
||||
}
|
||||
|
||||
public bool IsUserSubscribedToChatRoom(string accountId, string chatRoomId)
|
||||
{
|
||||
var userDeviceIds = ActiveConnections.Keys.Where(k => k.AccountId == accountId).Select(k => k.DeviceId);
|
||||
foreach (var deviceId in userDeviceIds)
|
||||
{
|
||||
if (ActiveSubscriptions.TryGetValue(deviceId, out var subscribedChatRoomId) &&
|
||||
subscribedChatRoomId == chatRoomId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryAdd(
|
||||
(string AccountId, string DeviceId) key,
|
||||
WebSocket socket,
|
||||
@@ -67,7 +42,11 @@ public class WebSocketService
|
||||
);
|
||||
data.Cts.Cancel();
|
||||
ActiveConnections.TryRemove(key, out _);
|
||||
UnsubscribeFromChatRoom(key.DeviceId);
|
||||
}
|
||||
|
||||
public bool GetDeviceIsConnected(string deviceId)
|
||||
{
|
||||
return ActiveConnections.Any(c => c.Key.DeviceId == deviceId);
|
||||
}
|
||||
|
||||
public bool GetAccountIsConnected(string accountId)
|
||||
|
@@ -1,15 +1,20 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using DysonNetwork.Shared.Auth;
|
||||
using DysonNetwork.Shared.Proto;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NodaTime;
|
||||
using AccountService = DysonNetwork.Shared.Proto.AccountService;
|
||||
|
||||
namespace DysonNetwork.Pusher.Notification;
|
||||
|
||||
[ApiController]
|
||||
[Route("/api/notifications")]
|
||||
public class NotificationController(AppDatabase db, NotificationService nty) : ControllerBase
|
||||
public class NotificationController(
|
||||
AppDatabase db,
|
||||
PushService nty,
|
||||
AccountService.AccountServiceClient accounts) : ControllerBase
|
||||
{
|
||||
[HttpGet("count")]
|
||||
[Authorize]
|
||||
@@ -17,9 +22,10 @@ public class NotificationController(AppDatabase db, NotificationService nty) : C
|
||||
{
|
||||
HttpContext.Items.TryGetValue("CurrentUser", out var currentUserValue);
|
||||
if (currentUserValue is not Account currentUser) return Unauthorized();
|
||||
var accountId = Guid.Parse(currentUser.Id);
|
||||
|
||||
var count = await db.Notifications
|
||||
.Where(s => s.AccountId == currentUser.Id && s.ViewedAt == null)
|
||||
.Where(s => s.AccountId == accountId && s.ViewedAt == null)
|
||||
.CountAsync();
|
||||
return Ok(count);
|
||||
}
|
||||
@@ -30,24 +36,25 @@ public class NotificationController(AppDatabase db, NotificationService nty) : C
|
||||
[FromQuery] int offset = 0,
|
||||
// The page size set to 5 is to avoid the client pulled the notification
|
||||
// but didn't render it in the screen-viewable region.
|
||||
[FromQuery] int take = 5
|
||||
[FromQuery] int take = 8
|
||||
)
|
||||
{
|
||||
HttpContext.Items.TryGetValue("CurrentUser", out var currentUserValue);
|
||||
if (currentUserValue is not Account currentUser) return Unauthorized();
|
||||
var accountId = Guid.Parse(currentUser.Id);
|
||||
|
||||
var totalCount = await db.Notifications
|
||||
.Where(s => s.AccountId == currentUser.Id)
|
||||
.Where(s => s.AccountId == accountId)
|
||||
.CountAsync();
|
||||
var notifications = await db.Notifications
|
||||
.Where(s => s.AccountId == currentUser.Id)
|
||||
.Where(s => s.AccountId == accountId)
|
||||
.OrderByDescending(e => e.CreatedAt)
|
||||
.Skip(offset)
|
||||
.Take(take)
|
||||
.ToListAsync();
|
||||
|
||||
Response.Headers["X-Total"] = totalCount.ToString();
|
||||
await nty.MarkNotificationsViewed(notifications);
|
||||
await nty.MarkNotificationsViewed(notifications.ToList());
|
||||
|
||||
return Ok(notifications);
|
||||
}
|
||||
@@ -55,14 +62,15 @@ public class NotificationController(AppDatabase db, NotificationService nty) : C
|
||||
public class PushNotificationSubscribeRequest
|
||||
{
|
||||
[MaxLength(4096)] public string DeviceToken { get; set; } = null!;
|
||||
public NotificationPushProvider Provider { get; set; }
|
||||
public PushProvider Provider { get; set; }
|
||||
}
|
||||
|
||||
[HttpPut("subscription")]
|
||||
[Authorize]
|
||||
public async Task<ActionResult<NotificationPushSubscription>> SubscribeToPushNotification(
|
||||
[FromBody] PushNotificationSubscribeRequest request
|
||||
)
|
||||
public async Task<ActionResult<PushSubscription>>
|
||||
SubscribeToPushNotification(
|
||||
[FromBody] PushNotificationSubscribeRequest request
|
||||
)
|
||||
{
|
||||
HttpContext.Items.TryGetValue("CurrentSession", out var currentSessionValue);
|
||||
HttpContext.Items.TryGetValue("CurrentUser", out var currentUserValue);
|
||||
@@ -72,8 +80,12 @@ public class NotificationController(AppDatabase db, NotificationService nty) : C
|
||||
if (currentSession == null) return Unauthorized();
|
||||
|
||||
var result =
|
||||
await nty.SubscribePushNotification(currentUser, request.Provider, currentSession.Challenge.DeviceId!,
|
||||
request.DeviceToken);
|
||||
await nty.SubscribeDevice(
|
||||
currentSession.Challenge.DeviceId!,
|
||||
request.DeviceToken,
|
||||
request.Provider,
|
||||
currentUser
|
||||
);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
@@ -88,10 +100,11 @@ public class NotificationController(AppDatabase db, NotificationService nty) : C
|
||||
if (currentUser == null) return Unauthorized();
|
||||
var currentSession = currentSessionValue as AuthSession;
|
||||
if (currentSession == null) return Unauthorized();
|
||||
var accountId = Guid.Parse(currentUser.Id);
|
||||
|
||||
var affectedRows = await db.NotificationPushSubscriptions
|
||||
var affectedRows = await db.PushSubscriptions
|
||||
.Where(s =>
|
||||
s.AccountId == currentUser.Id &&
|
||||
s.AccountId == accountId &&
|
||||
s.DeviceId == currentSession.Challenge.DeviceId
|
||||
).ExecuteDeleteAsync();
|
||||
return Ok(affectedRows);
|
||||
@@ -107,36 +120,11 @@ public class NotificationController(AppDatabase db, NotificationService nty) : C
|
||||
public int Priority { get; set; } = 10;
|
||||
}
|
||||
|
||||
[HttpPost("broadcast")]
|
||||
[Authorize]
|
||||
[RequiredPermission("global", "notifications.broadcast")]
|
||||
public async Task<ActionResult> BroadcastNotification(
|
||||
[FromBody] NotificationRequest request,
|
||||
[FromQuery] bool save = false
|
||||
)
|
||||
{
|
||||
await nty.BroadcastNotification(
|
||||
new Notification
|
||||
{
|
||||
CreatedAt = SystemClock.Instance.GetCurrentInstant(),
|
||||
UpdatedAt = SystemClock.Instance.GetCurrentInstant(),
|
||||
Topic = request.Topic,
|
||||
Title = request.Title,
|
||||
Subtitle = request.Subtitle,
|
||||
Content = request.Content,
|
||||
Meta = request.Meta,
|
||||
Priority = request.Priority,
|
||||
},
|
||||
save
|
||||
);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
public class NotificationWithAimRequest : NotificationRequest
|
||||
{
|
||||
[Required] public List<Guid> AccountId { get; set; } = null!;
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("send")]
|
||||
[Authorize]
|
||||
[RequiredPermission("global", "notifications.send")]
|
||||
@@ -145,7 +133,6 @@ public class NotificationController(AppDatabase db, NotificationService nty) : C
|
||||
[FromQuery] bool save = false
|
||||
)
|
||||
{
|
||||
var accounts = await db.Accounts.Where(a => request.AccountId.Contains(a.Id)).ToListAsync();
|
||||
await nty.SendNotificationBatch(
|
||||
new Notification
|
||||
{
|
||||
@@ -157,7 +144,7 @@ public class NotificationController(AppDatabase db, NotificationService nty) : C
|
||||
Content = request.Content,
|
||||
Meta = request.Meta,
|
||||
},
|
||||
accounts,
|
||||
request.AccountId,
|
||||
save
|
||||
);
|
||||
return Ok();
|
||||
|
@@ -12,14 +12,14 @@ public class PushService(IConfiguration config, AppDatabase db, IHttpClientFacto
|
||||
private readonly string _notifyTopic = config["Notifications:Topic"]!;
|
||||
private readonly Uri _notifyEndpoint = new(config["Notifications:Endpoint"]!);
|
||||
|
||||
public async Task UnsubscribePushNotifications(string deviceId)
|
||||
public async Task UnsubscribeDevice(string deviceId)
|
||||
{
|
||||
await db.PushSubscriptions
|
||||
.Where(s => s.DeviceId == deviceId)
|
||||
.ExecuteDeleteAsync();
|
||||
}
|
||||
|
||||
public async Task<PushSubscription> SubscribePushNotification(
|
||||
public async Task<PushSubscription> SubscribeDevice(
|
||||
string deviceId,
|
||||
string deviceToken,
|
||||
PushProvider provider,
|
||||
|
@@ -9,7 +9,7 @@ namespace DysonNetwork.Pusher.Services;
|
||||
|
||||
public class PusherServiceGrpc(
|
||||
EmailService emailService,
|
||||
WebSocketService webSocketService,
|
||||
WebSocketService websocket,
|
||||
PushService pushService
|
||||
) : PusherService.PusherServiceBase
|
||||
{
|
||||
@@ -32,7 +32,7 @@ public class PusherServiceGrpc(
|
||||
Data = request.Packet.Data,
|
||||
ErrorMessage = request.Packet.ErrorMessage
|
||||
};
|
||||
webSocketService.SendPacketToAccount(request.UserId, packet);
|
||||
websocket.SendPacketToAccount(request.UserId, packet);
|
||||
return Task.FromResult(new Empty());
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public class PusherServiceGrpc(
|
||||
ErrorMessage = request.Packet.ErrorMessage
|
||||
};
|
||||
foreach (var userId in request.UserIds)
|
||||
webSocketService.SendPacketToAccount(userId, packet);
|
||||
websocket.SendPacketToAccount(userId, packet);
|
||||
|
||||
return Task.FromResult(new Empty());
|
||||
}
|
||||
@@ -60,7 +60,7 @@ public class PusherServiceGrpc(
|
||||
Data = request.Packet.Data,
|
||||
ErrorMessage = request.Packet.ErrorMessage
|
||||
};
|
||||
webSocketService.SendPacketToDevice(request.DeviceId, packet);
|
||||
websocket.SendPacketToDevice(request.DeviceId, packet);
|
||||
return Task.FromResult(new Empty());
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public class PusherServiceGrpc(
|
||||
ErrorMessage = request.Packet.ErrorMessage
|
||||
};
|
||||
foreach (var deviceId in request.DeviceIds)
|
||||
webSocketService.SendPacketToDevice(deviceId, packet);
|
||||
websocket.SendPacketToDevice(deviceId, packet);
|
||||
|
||||
return Task.FromResult(new Empty());
|
||||
}
|
||||
@@ -159,4 +159,22 @@ public class PusherServiceGrpc(
|
||||
await pushService.SendNotificationBatch(notification, accounts, request.Notification.IsSavable);
|
||||
return new Empty();
|
||||
}
|
||||
|
||||
public override async Task<Empty> UnsubscribePushNotifications(UnsubscribePushNotificationsRequest request, ServerCallContext context)
|
||||
{
|
||||
await pushService.UnsubscribeDevice(request.DeviceId);
|
||||
return new Empty();
|
||||
}
|
||||
|
||||
public override Task<GetWebsocketConnectionStatusResponse> GetWebsocketConnectionStatus(GetWebsocketConnectionStatusRequest request, ServerCallContext context)
|
||||
{
|
||||
var isConnected = request.IdCase switch
|
||||
{
|
||||
GetWebsocketConnectionStatusRequest.IdOneofCase.DeviceId => websocket.GetDeviceIsConnected(request.DeviceId),
|
||||
GetWebsocketConnectionStatusRequest.IdOneofCase.UserId => websocket.GetAccountIsConnected(request.UserId),
|
||||
_ => false
|
||||
};
|
||||
|
||||
return Task.FromResult(new GetWebsocketConnectionStatusResponse { IsConnected = isConnected });
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user