Compare commits

...

3 Commits

Author SHA1 Message Date
7ddb904335 Public contacts 2025-08-08 23:31:05 +08:00
c514adfbbf Profile links 2025-08-08 23:28:24 +08:00
a32c06552f 👔 Change the post featured period counting to a week 2025-08-08 23:26:08 +08:00
10 changed files with 3625 additions and 4 deletions

View File

@@ -125,6 +125,7 @@ public class AccountProfile : ModelBase, IIdentifiedResource
[MaxLength(1024)] public string? Pronouns { get; set; }
[MaxLength(1024)] public string? TimeZone { get; set; }
[MaxLength(1024)] public string? Location { get; set; }
[Column(TypeName = "jsonb")] public Dictionary<string, string>? Links { get; set; }
public Instant? Birthday { get; set; }
public Instant? LastSeenAt { get; set; }
@@ -213,6 +214,7 @@ public class AccountContact : ModelBase
public AccountContactType Type { get; set; }
public Instant? VerifiedAt { get; set; }
public bool IsPrimary { get; set; } = false;
public bool IsPublic { get; set; } = false;
[MaxLength(1024)] public string Content { get; set; } = string.Empty;
public Guid AccountId { get; set; }

View File

@@ -25,6 +25,7 @@ public class AccountController(
var account = await db.Accounts
.Include(e => e.Badges)
.Include(e => e.Profile)
.Include(e => e.Contacts.Where(c => c.IsPublic))
.Where(a => a.Name == name)
.FirstOrDefaultAsync();
if (account is null) return new NotFoundResult();

View File

@@ -77,6 +77,7 @@ public class AccountCurrentController(
[MaxLength(1024)] public string? Location { get; set; }
[MaxLength(4096)] public string? Bio { get; set; }
public Instant? Birthday { get; set; }
public Dictionary<string, string>? Links { get; set; }
[MaxLength(32)] public string? PictureId { get; set; }
[MaxLength(32)] public string? BackgroundId { get; set; }
@@ -102,6 +103,7 @@ public class AccountCurrentController(
if (request.Birthday is not null) profile.Birthday = request.Birthday;
if (request.Location is not null) profile.Location = request.Location;
if (request.TimeZone is not null) profile.TimeZone = request.TimeZone;
if (request.Links is not null) profile.Links = request.Links;
if (request.PictureId is not null)
{
@@ -651,6 +653,50 @@ public class AccountCurrentController(
return BadRequest(ex.Message);
}
}
[HttpPost("contacts/{id:guid}/public")]
[Authorize]
public async Task<ActionResult<AccountContact>> SetPublicContact(Guid id)
{
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
var contact = await db.AccountContacts
.Where(c => c.AccountId == currentUser.Id && c.Id == id)
.FirstOrDefaultAsync();
if (contact is null) return NotFound();
try
{
contact = await accounts.SetContactMethodPublic(currentUser, contact, true);
return Ok(contact);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpDelete("contacts/{id:guid}/public")]
[Authorize]
public async Task<ActionResult<AccountContact>> UnsetPublicContact(Guid id)
{
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
var contact = await db.AccountContacts
.Where(c => c.AccountId == currentUser.Id && c.Id == id)
.FirstOrDefaultAsync();
if (contact is null) return NotFound();
try
{
contact = await accounts.SetContactMethodPublic(currentUser, contact, false);
return Ok(contact);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpDelete("contacts/{id:guid}")]
[Authorize]

View File

@@ -557,6 +557,14 @@ public class AccountService(
throw;
}
}
public async Task<AccountContact> SetContactMethodPublic(Account account, AccountContact contact, bool isPublic)
{
contact.IsPublic = isPublic;
db.AccountContacts.Update(contact);
await db.SaveChangesAsync();
return contact;
}
public async Task DeleteContactMethod(Account account, AccountContact contact)
{

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace DysonNetwork.Pass.Migrations
{
/// <inheritdoc />
public partial class AddProfileLinks : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<Dictionary<string, string>>(
name: "links",
table: "account_profiles",
type: "jsonb",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "links",
table: "account_profiles");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace DysonNetwork.Pass.Migrations
{
/// <inheritdoc />
public partial class AddPublicContact : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "is_public",
table: "account_contacts",
type: "boolean",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "is_public",
table: "account_contacts");
}
}
}

View File

@@ -351,6 +351,10 @@ namespace DysonNetwork.Pass.Migrations
.HasColumnType("boolean")
.HasColumnName("is_primary");
b.Property<bool>("IsPublic")
.HasColumnType("boolean")
.HasColumnName("is_public");
b.Property<int>("Type")
.HasColumnType("integer")
.HasColumnName("type");
@@ -431,6 +435,10 @@ namespace DysonNetwork.Pass.Migrations
.HasColumnType("timestamp with time zone")
.HasColumnName("last_seen_at");
b.Property<Dictionary<string, string>>("Links")
.HasColumnType("jsonb")
.HasColumnName("links");
b.Property<string>("Location")
.HasMaxLength(1024)
.HasColumnType("character varying(1024)")

View File

@@ -741,13 +741,13 @@ public partial class PostService(
if (featuredIds is null)
{
var today = SystemClock.Instance.GetCurrentInstant();
var todayStart = today.InUtc().Date.AtStartOfDayInZone(DateTimeZone.Utc).ToInstant();
var todayEnd = today.InUtc().Date.PlusDays(1).AtStartOfDayInZone(DateTimeZone.Utc).ToInstant();
var periodStart = today.InUtc().Date.AtStartOfDayInZone(DateTimeZone.Utc).ToInstant().Minus(Duration.FromDays(7));
var periodEnd = today.InUtc().Date.PlusDays(1).AtStartOfDayInZone(DateTimeZone.Utc).ToInstant();
var reactSocialPoints = await db.PostReactions
.Include(e => e.Post)
.Where(e => e.Post.Visibility == PostVisibility.Public)
.Where(e => e.CreatedAt >= todayStart && e.CreatedAt < todayEnd)
.Where(e => e.CreatedAt >= periodStart && e.CreatedAt < periodEnd)
.GroupBy(e => e.PostId)
.Select(e => new
{