🐛 Fix bugs
This commit is contained in:
parent
4fd8a588fa
commit
790dcafeb0
@ -224,6 +224,44 @@ public class AccountController(
|
|||||||
return Ok(status);
|
return Ok(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("{name}/statuses")]
|
||||||
|
public async Task<ActionResult<Status>> GetOtherStatus(string name)
|
||||||
|
{
|
||||||
|
var account = await db.Accounts.FirstOrDefaultAsync(a => a.Name == name);
|
||||||
|
if (account is null) return BadRequest();
|
||||||
|
var status = await events.GetStatus(account.Id);
|
||||||
|
status.IsInvisible = false; // Keep the invisible field not available for other users
|
||||||
|
return Ok(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPatch("me/statuses")]
|
||||||
|
[Authorize]
|
||||||
|
[RequiredPermission("global", "accounts.statuses.update")]
|
||||||
|
public async Task<ActionResult<Status>> UpdateStatus([FromBody] StatusRequest request)
|
||||||
|
{
|
||||||
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
||||||
|
|
||||||
|
var now = SystemClock.Instance.GetCurrentInstant();
|
||||||
|
var status = await db.AccountStatuses
|
||||||
|
.Where(e => e.AccountId == currentUser.Id)
|
||||||
|
.Where(e => e.ClearedAt == null || e.ClearedAt > now)
|
||||||
|
.OrderByDescending(e => e.CreatedAt)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
if (status is null) return NotFound();
|
||||||
|
|
||||||
|
status.Attitude = request.Attitude;
|
||||||
|
status.IsInvisible = request.IsInvisible;
|
||||||
|
status.IsNotDisturb = request.IsNotDisturb;
|
||||||
|
status.Label = request.Label;
|
||||||
|
status.ClearedAt = request.ClearedAt;
|
||||||
|
|
||||||
|
db.Update(status);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
events.PurgeStatusCache(currentUser.Id);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost("me/statuses")]
|
[HttpPost("me/statuses")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[RequiredPermission("global", "accounts.statuses.create")]
|
[RequiredPermission("global", "accounts.statuses.create")]
|
||||||
@ -305,7 +343,8 @@ public class AccountController(
|
|||||||
|
|
||||||
[HttpGet("me/calendar")]
|
[HttpGet("me/calendar")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public async Task<ActionResult<List<DailyEventResponse>>> GetEventCalendar([FromQuery] int? month, [FromQuery] int? year)
|
public async Task<ActionResult<List<DailyEventResponse>>> GetEventCalendar([FromQuery] int? month,
|
||||||
|
[FromQuery] int? year)
|
||||||
{
|
{
|
||||||
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
||||||
|
|
||||||
@ -320,6 +359,27 @@ public class AccountController(
|
|||||||
return Ok(calendar);
|
return Ok(calendar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("{name}/calendar")]
|
||||||
|
public async Task<ActionResult<List<DailyEventResponse>>> GetOtherEventCalendar(
|
||||||
|
string name,
|
||||||
|
[FromQuery] int? month,
|
||||||
|
[FromQuery] int? year
|
||||||
|
)
|
||||||
|
{
|
||||||
|
var currentDate = SystemClock.Instance.GetCurrentInstant().InUtc().Date;
|
||||||
|
month ??= currentDate.Month;
|
||||||
|
year ??= currentDate.Year;
|
||||||
|
|
||||||
|
if (month is < 1 or > 12) return BadRequest("Invalid month.");
|
||||||
|
if (year < 1) return BadRequest("Invalid year.");
|
||||||
|
|
||||||
|
var account = await db.Accounts.FirstOrDefaultAsync(a => a.Name == name);
|
||||||
|
if (account is null) return BadRequest();
|
||||||
|
|
||||||
|
var calendar = await events.GetEventCalendar(account, month.Value, year.Value, replaceInvisible: true);
|
||||||
|
return Ok(calendar);
|
||||||
|
}
|
||||||
|
|
||||||
[HttpGet("search")]
|
[HttpGet("search")]
|
||||||
public async Task<List<Account>> Search([FromQuery] string query, [FromQuery] int take = 20)
|
public async Task<List<Account>> Search([FromQuery] string query, [FromQuery] int take = 20)
|
||||||
{
|
{
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using DysonNetwork.Sphere.Activity;
|
using DysonNetwork.Sphere.Activity;
|
||||||
using DysonNetwork.Sphere.Connection;
|
using DysonNetwork.Sphere.Connection;
|
||||||
using DysonNetwork.Sphere.Resources;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using Microsoft.Extensions.Localization;
|
using Microsoft.Extensions.Localization;
|
||||||
using NodaTime;
|
using NodaTime;
|
||||||
using NodaTime;
|
|
||||||
|
|
||||||
namespace DysonNetwork.Sphere.Account;
|
namespace DysonNetwork.Sphere.Account;
|
||||||
|
|
||||||
@ -21,11 +19,20 @@ public class AccountEventService(
|
|||||||
private static readonly Random Random = new();
|
private static readonly Random Random = new();
|
||||||
private const string StatusCacheKey = "account_status_";
|
private const string StatusCacheKey = "account_status_";
|
||||||
|
|
||||||
|
public void PurgeStatusCache(long userId)
|
||||||
|
{
|
||||||
|
var cacheKey = $"{StatusCacheKey}{userId}";
|
||||||
|
cache.Remove(cacheKey);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<Status> GetStatus(long userId)
|
public async Task<Status> GetStatus(long userId)
|
||||||
{
|
{
|
||||||
var cacheKey = $"{StatusCacheKey}{userId}";
|
var cacheKey = $"{StatusCacheKey}{userId}";
|
||||||
if (cache.TryGetValue(cacheKey, out Status? cachedStatus))
|
if (cache.TryGetValue(cacheKey, out Status? cachedStatus))
|
||||||
return cachedStatus!;
|
{
|
||||||
|
cachedStatus!.IsOnline = !cachedStatus.IsInvisible && ws.GetAccountIsConnected(userId);
|
||||||
|
return cachedStatus;
|
||||||
|
}
|
||||||
|
|
||||||
var now = SystemClock.Instance.GetCurrentInstant();
|
var now = SystemClock.Instance.GetCurrentInstant();
|
||||||
var status = await db.AccountStatuses
|
var status = await db.AccountStatuses
|
||||||
@ -33,19 +40,21 @@ public class AccountEventService(
|
|||||||
.Where(e => e.ClearedAt == null || e.ClearedAt > now)
|
.Where(e => e.ClearedAt == null || e.ClearedAt > now)
|
||||||
.OrderByDescending(e => e.CreatedAt)
|
.OrderByDescending(e => e.CreatedAt)
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
|
var isOnline = ws.GetAccountIsConnected(userId);
|
||||||
if (status is not null)
|
if (status is not null)
|
||||||
{
|
{
|
||||||
|
status.IsOnline = !status.IsInvisible && isOnline;
|
||||||
cache.Set(cacheKey, status, TimeSpan.FromMinutes(5));
|
cache.Set(cacheKey, status, TimeSpan.FromMinutes(5));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isOnline = ws.GetAccountIsConnected(userId);
|
|
||||||
if (isOnline)
|
if (isOnline)
|
||||||
{
|
{
|
||||||
return new Status
|
return new Status
|
||||||
{
|
{
|
||||||
Attitude = StatusAttitude.Neutral,
|
Attitude = StatusAttitude.Neutral,
|
||||||
IsOnline = true,
|
IsOnline = true,
|
||||||
|
IsCustomized = false,
|
||||||
Label = "Online",
|
Label = "Online",
|
||||||
AccountId = userId,
|
AccountId = userId,
|
||||||
};
|
};
|
||||||
@ -55,6 +64,7 @@ public class AccountEventService(
|
|||||||
{
|
{
|
||||||
Attitude = StatusAttitude.Neutral,
|
Attitude = StatusAttitude.Neutral,
|
||||||
IsOnline = false,
|
IsOnline = false,
|
||||||
|
IsCustomized = false,
|
||||||
Label = "Offline",
|
Label = "Offline",
|
||||||
AccountId = userId,
|
AccountId = userId,
|
||||||
};
|
};
|
||||||
@ -85,6 +95,7 @@ public class AccountEventService(
|
|||||||
status.ClearedAt = SystemClock.Instance.GetCurrentInstant();
|
status.ClearedAt = SystemClock.Instance.GetCurrentInstant();
|
||||||
db.Update(status);
|
db.Update(status);
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
|
PurgeStatusCache(user.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private const int FortuneTipCount = 7; // This will be the max index for each type (positive/negative)
|
private const int FortuneTipCount = 7; // This will be the max index for each type (positive/negative)
|
||||||
@ -168,7 +179,8 @@ public class AccountEventService(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<DailyEventResponse>> GetEventCalendar(Account user, int month, int year = 0)
|
public async Task<List<DailyEventResponse>> GetEventCalendar(Account user, int month, int year = 0,
|
||||||
|
bool replaceInvisible = false)
|
||||||
{
|
{
|
||||||
if (year == 0)
|
if (year == 0)
|
||||||
year = SystemClock.Instance.GetCurrentInstant().InUtc().Date.Year;
|
year = SystemClock.Instance.GetCurrentInstant().InUtc().Date.Year;
|
||||||
@ -178,11 +190,26 @@ public async Task<List<DailyEventResponse>> GetEventCalendar(Account user, int m
|
|||||||
var endOfMonth = startOfMonth.Plus(Duration.FromDays(DateTime.DaysInMonth(year, month)));
|
var endOfMonth = startOfMonth.Plus(Duration.FromDays(DateTime.DaysInMonth(year, month)));
|
||||||
|
|
||||||
var statuses = await db.AccountStatuses
|
var statuses = await db.AccountStatuses
|
||||||
|
.AsNoTracking()
|
||||||
|
.TagWith("GetEventCalendar_Statuses")
|
||||||
.Where(x => x.AccountId == user.Id && x.CreatedAt >= startOfMonth && x.CreatedAt < endOfMonth)
|
.Where(x => x.AccountId == user.Id && x.CreatedAt >= startOfMonth && x.CreatedAt < endOfMonth)
|
||||||
|
.Select(x => new Status
|
||||||
|
{
|
||||||
|
Id = x.Id,
|
||||||
|
Attitude = x.Attitude,
|
||||||
|
IsInvisible = !replaceInvisible && x.IsInvisible,
|
||||||
|
IsNotDisturb = x.IsNotDisturb,
|
||||||
|
Label = x.Label,
|
||||||
|
ClearedAt = x.ClearedAt,
|
||||||
|
AccountId = x.AccountId,
|
||||||
|
CreatedAt = x.CreatedAt
|
||||||
|
})
|
||||||
.OrderBy(x => x.CreatedAt)
|
.OrderBy(x => x.CreatedAt)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
var checkIn = await db.AccountCheckInResults
|
var checkIn = await db.AccountCheckInResults
|
||||||
|
.AsNoTracking()
|
||||||
|
.TagWith("GetEventCalendar_CheckIn")
|
||||||
.Where(x => x.AccountId == user.Id && x.CreatedAt >= startOfMonth && x.CreatedAt < endOfMonth)
|
.Where(x => x.AccountId == user.Id && x.CreatedAt >= startOfMonth && x.CreatedAt < endOfMonth)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ public class Status : ModelBase
|
|||||||
public Guid Id { get; set; } = Guid.NewGuid();
|
public Guid Id { get; set; } = Guid.NewGuid();
|
||||||
public StatusAttitude Attitude { get; set; }
|
public StatusAttitude Attitude { get; set; }
|
||||||
[NotMapped] public bool IsOnline { get; set; }
|
[NotMapped] public bool IsOnline { get; set; }
|
||||||
|
[NotMapped] public bool IsCustomized { get; set; } = true;
|
||||||
public bool IsInvisible { get; set; }
|
public bool IsInvisible { get; set; }
|
||||||
public bool IsNotDisturb { get; set; }
|
public bool IsNotDisturb { get; set; }
|
||||||
[MaxLength(1024)] public string? Label { get; set; }
|
[MaxLength(1024)] public string? Label { get; set; }
|
||||||
|
@ -90,7 +90,8 @@ public class AppDatabase(
|
|||||||
PermissionService.NewPermissionNode("group:default", "global", "chat.create", true),
|
PermissionService.NewPermissionNode("group:default", "global", "chat.create", true),
|
||||||
PermissionService.NewPermissionNode("group:default", "global", "chat.messages.create", true),
|
PermissionService.NewPermissionNode("group:default", "global", "chat.messages.create", true),
|
||||||
PermissionService.NewPermissionNode("group:default", "global", "chat.realtime.create", true),
|
PermissionService.NewPermissionNode("group:default", "global", "chat.realtime.create", true),
|
||||||
PermissionService.NewPermissionNode("group:default", "global", "accounts.statuses.create", true)
|
PermissionService.NewPermissionNode("group:default", "global", "accounts.statuses.create", true),
|
||||||
|
PermissionService.NewPermissionNode("group:default", "global", "accounts.statuses.update", true)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await context.SaveChangesAsync(cancellationToken);
|
await context.SaveChangesAsync(cancellationToken);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user