feat: so much more frontend stuff
This commit is contained in:
parent
c179669799
commit
261435c252
24 changed files with 682 additions and 107 deletions
|
@ -1,4 +1,5 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using Coravel.Mailer.Mail.Helpers;
|
||||
using Coravel.Queuing.Interfaces;
|
||||
using EntityFramework.Exceptions.Common;
|
||||
using Foxnouns.Backend.Database;
|
||||
|
@ -116,6 +117,42 @@ public class UsersController(
|
|||
if (req.HasProperty(nameof(req.Avatar)))
|
||||
errors.Add(("avatar", ValidationUtils.ValidateAvatar(req.Avatar)));
|
||||
|
||||
if (req.HasProperty(nameof(req.MemberTitle)))
|
||||
{
|
||||
if (string.IsNullOrEmpty(req.MemberTitle))
|
||||
{
|
||||
user.MemberTitle = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(("member_title", ValidationUtils.ValidateDisplayName(req.MemberTitle)));
|
||||
user.MemberTitle = req.MemberTitle;
|
||||
}
|
||||
}
|
||||
|
||||
if (req.HasProperty(nameof(req.MemberListHidden)))
|
||||
user.ListHidden = req.MemberListHidden == true;
|
||||
|
||||
if (req.HasProperty(nameof(req.Timezone)))
|
||||
{
|
||||
if (string.IsNullOrEmpty(req.Timezone))
|
||||
{
|
||||
user.Timezone = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TimeZoneInfo.TryFindSystemTimeZoneById(req.Timezone, out _))
|
||||
user.Timezone = req.Timezone;
|
||||
else
|
||||
errors.Add(
|
||||
(
|
||||
"timezone",
|
||||
ValidationError.GenericValidationError("Invalid timezone", req.Timezone)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ValidationUtils.Validate(errors);
|
||||
// This is fired off regardless of whether the transaction is committed
|
||||
// (atomic operations are hard when combined with background jobs)
|
||||
|
@ -253,6 +290,9 @@ public class UsersController(
|
|||
public Pronoun[]? Pronouns { get; init; }
|
||||
public Field[]? Fields { get; init; }
|
||||
public Snowflake[]? Flags { get; init; }
|
||||
public string? MemberTitle { get; init; }
|
||||
public bool? MemberListHidden { get; init; }
|
||||
public string? Timezone { get; init; }
|
||||
}
|
||||
|
||||
[HttpGet("@me/settings")]
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Foxnouns.Backend.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
[DbContext(typeof(DatabaseContext))]
|
||||
[Migration("20241124201309_AddUserTimezone")]
|
||||
public partial class AddUserTimezone : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "timezone",
|
||||
table: "users",
|
||||
type: "text",
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "timezone", table: "users");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -434,6 +434,10 @@ namespace Foxnouns.Backend.Database.Migrations
|
|||
.HasColumnName("sid")
|
||||
.HasDefaultValueSql("find_free_user_sid()");
|
||||
|
||||
b.Property<string>("Timezone")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("timezone");
|
||||
|
||||
b.Property<string>("Username")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
|
|
|
@ -15,6 +15,7 @@ public class User : BaseModel
|
|||
public string? Avatar { get; set; }
|
||||
public string[] Links { get; set; } = [];
|
||||
public bool ListHidden { get; set; }
|
||||
public string? Timezone { get; set; }
|
||||
|
||||
public List<FieldEntry> Names { get; set; } = [];
|
||||
public List<Pronoun> Pronouns { get; set; } = [];
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
"Development": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"hotReloadEnabled": false,
|
||||
"launchBrowser": false,
|
||||
"externalUrlConfiguration": true,
|
||||
"environmentVariables": {
|
||||
|
@ -13,6 +14,7 @@
|
|||
"Production": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"hotReloadEnabled": false,
|
||||
"launchBrowser": false,
|
||||
"externalUrlConfiguration": true,
|
||||
"environmentVariables": {
|
||||
|
|
|
@ -4,6 +4,7 @@ using Foxnouns.Backend.Utils;
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
using NodaTime;
|
||||
using Org.BouncyCastle.Ocsp;
|
||||
|
||||
namespace Foxnouns.Backend.Services;
|
||||
|
||||
|
@ -49,6 +50,13 @@ public class UserRendererService(
|
|||
.ToListAsync(ct)
|
||||
: [];
|
||||
|
||||
int? utcOffset = null;
|
||||
if (
|
||||
user.Timezone != null
|
||||
&& TimeZoneInfo.TryFindSystemTimeZoneById(user.Timezone, out var tz)
|
||||
)
|
||||
utcOffset = (int)tz.GetUtcOffset(DateTimeOffset.UtcNow).TotalSeconds;
|
||||
|
||||
return new UserResponse(
|
||||
user.Id,
|
||||
user.Sid,
|
||||
|
@ -63,6 +71,7 @@ public class UserRendererService(
|
|||
user.Fields,
|
||||
user.CustomPreferences,
|
||||
flags.Select(f => RenderPrideFlag(f.PrideFlag)),
|
||||
utcOffset,
|
||||
user.Role,
|
||||
renderMembers
|
||||
? members.Select(m => memberRenderer.RenderPartialMember(m, tokenHidden))
|
||||
|
@ -70,7 +79,8 @@ public class UserRendererService(
|
|||
renderAuthMethods ? authMethods.Select(RenderAuthMethod) : null,
|
||||
tokenHidden ? user.ListHidden : null,
|
||||
tokenHidden ? user.LastActive : null,
|
||||
tokenHidden ? user.LastSidReroll : null
|
||||
tokenHidden ? user.LastSidReroll : null,
|
||||
tokenHidden ? user.Timezone ?? "<none>" : null
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -115,6 +125,7 @@ public class UserRendererService(
|
|||
IEnumerable<Field> Fields,
|
||||
Dictionary<Snowflake, User.CustomPreference> CustomPreferences,
|
||||
IEnumerable<PrideFlagResponse> Flags,
|
||||
int? UtcOffset,
|
||||
[property: JsonConverter(typeof(ScreamingSnakeCaseEnumConverter))] UserRole Role,
|
||||
[property: JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
IEnumerable<MemberRendererService.PartialMember>? Members,
|
||||
|
@ -124,7 +135,8 @@ public class UserRendererService(
|
|||
bool? MemberListHidden,
|
||||
[property: JsonProperty(NullValueHandling = NullValueHandling.Ignore)] Instant? LastActive,
|
||||
[property: JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
Instant? LastSidReroll
|
||||
Instant? LastSidReroll,
|
||||
[property: JsonProperty(NullValueHandling = NullValueHandling.Ignore)] string? Timezone
|
||||
);
|
||||
|
||||
public record AuthMethodResponse(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue