.github
.idx
DysonNetwork.Sphere
Account
Account.cs
AccountController.cs
AccountCurrentController.cs
AccountEventService.cs
AccountService.cs
ActionLog.cs
ActionLogService.cs
Badge.cs
Event.cs
MagicSpell.cs
MagicSpellController.cs
MagicSpellService.cs
Notification.cs
NotificationController.cs
NotificationService.cs
Relationship.cs
RelationshipController.cs
RelationshipService.cs
Activity
Auth
Chat
Connection
Developer
Email
Localization
Migrations
Pages
Permission
Post
Properties
Publisher
Realm
Resources
Sticker
Storage
Wallet
wwwroot
.DS_Store
.gitignore
AppDatabase.cs
Dockerfile
DysonNetwork.Sphere.csproj
DysonNetwork.Sphere.csproj.DotSettings.user
DysonNetwork.Sphere.http
Program.cs
appsettings.json
package.json
postcss.config.js
tailwind.config.js
.dockerignore
.gitignore
DysonNetwork.sln
DysonNetwork.sln.DotSettings.user
compose.yaml
210 lines
7.0 KiB
C#
210 lines
7.0 KiB
C#
using System.ComponentModel.DataAnnotations;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace DysonNetwork.Sphere.Account;
|
|
|
|
[ApiController]
|
|
[Route("/relationships")]
|
|
public class RelationshipController(AppDatabase db, RelationshipService rels) : ControllerBase
|
|
{
|
|
[HttpGet]
|
|
[Authorize]
|
|
public async Task<ActionResult<List<Relationship>>> ListRelationships([FromQuery] int offset = 0,
|
|
[FromQuery] int take = 20)
|
|
{
|
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
|
var userId = currentUser.Id;
|
|
|
|
var query = db.AccountRelationships.AsQueryable()
|
|
.Where(r => r.RelatedId == userId);
|
|
var totalCount = await query.CountAsync();
|
|
var relationships = await query
|
|
.Include(r => r.Related)
|
|
.Include(r => r.Related.Profile)
|
|
.Include(r => r.Account)
|
|
.Include(r => r.Account.Profile)
|
|
.Skip(offset)
|
|
.Take(take)
|
|
.ToListAsync();
|
|
|
|
var statuses = await db.AccountRelationships
|
|
.Where(r => r.AccountId == userId)
|
|
.ToDictionaryAsync(r => r.AccountId);
|
|
foreach (var relationship in relationships)
|
|
if (statuses.TryGetValue(relationship.RelatedId, out var status))
|
|
relationship.Status = status.Status;
|
|
|
|
Response.Headers["X-Total"] = totalCount.ToString();
|
|
|
|
return relationships;
|
|
}
|
|
|
|
[HttpGet("requests")]
|
|
[Authorize]
|
|
public async Task<ActionResult<List<Relationship>>> ListSentRequests()
|
|
{
|
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
|
|
|
var relationships = await db.AccountRelationships
|
|
.Where(r => r.AccountId == currentUser.Id && r.Status == RelationshipStatus.Pending)
|
|
.Include(r => r.Related)
|
|
.Include(r => r.Related.Profile)
|
|
.Include(r => r.Account)
|
|
.Include(r => r.Account.Profile)
|
|
.ToListAsync();
|
|
|
|
return relationships;
|
|
}
|
|
|
|
public class RelationshipRequest
|
|
{
|
|
[Required] public RelationshipStatus Status { get; set; }
|
|
}
|
|
|
|
[HttpPost("{userId:guid}")]
|
|
[Authorize]
|
|
public async Task<ActionResult<Relationship>> CreateRelationship(Guid userId, [FromBody] RelationshipRequest request)
|
|
{
|
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
|
|
|
var relatedUser = await db.Accounts.FindAsync(userId);
|
|
if (relatedUser is null) return NotFound("Account was not found.");
|
|
|
|
try
|
|
{
|
|
var relationship = await rels.CreateRelationship(
|
|
currentUser, relatedUser, request.Status
|
|
);
|
|
return relationship;
|
|
}
|
|
catch (InvalidOperationException err)
|
|
{
|
|
return BadRequest(err.Message);
|
|
}
|
|
}
|
|
|
|
[HttpPatch("{userId:guid}")]
|
|
[Authorize]
|
|
public async Task<ActionResult<Relationship>> UpdateRelationship(Guid userId, [FromBody] RelationshipRequest request)
|
|
{
|
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
|
|
|
try
|
|
{
|
|
var relationship = await rels.UpdateRelationship(currentUser.Id, userId, request.Status);
|
|
return relationship;
|
|
}
|
|
catch (ArgumentException err)
|
|
{
|
|
return NotFound(err.Message);
|
|
}
|
|
catch (InvalidOperationException err)
|
|
{
|
|
return BadRequest(err.Message);
|
|
}
|
|
}
|
|
|
|
[HttpPost("{userId:guid}/friends")]
|
|
[Authorize]
|
|
public async Task<ActionResult<Relationship>> SendFriendRequest(Guid userId)
|
|
{
|
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
|
|
|
var relatedUser = await db.Accounts.FindAsync(userId);
|
|
if (relatedUser is null) return NotFound("Account was not found.");
|
|
|
|
var existing = await db.AccountRelationships.FirstOrDefaultAsync(r =>
|
|
(r.AccountId == currentUser.Id && r.RelatedId == userId) ||
|
|
(r.AccountId == userId && r.RelatedId == currentUser.Id));
|
|
if (existing != null) return BadRequest("Relationship already exists.");
|
|
|
|
try
|
|
{
|
|
var relationship = await rels.SendFriendRequest(currentUser, relatedUser);
|
|
return relationship;
|
|
}
|
|
catch (InvalidOperationException err)
|
|
{
|
|
return BadRequest(err.Message);
|
|
}
|
|
}
|
|
|
|
[HttpDelete("{userId:guid}/friends")]
|
|
[Authorize]
|
|
public async Task<ActionResult> DeleteFriendRequest(Guid userId)
|
|
{
|
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
|
|
|
try
|
|
{
|
|
await rels.DeleteFriendRequest(currentUser.Id, userId);
|
|
return NoContent();
|
|
}
|
|
catch (ArgumentException err)
|
|
{
|
|
return NotFound(err.Message);
|
|
}
|
|
}
|
|
|
|
[HttpPost("{userId:guid}/friends/accept")]
|
|
[Authorize]
|
|
public async Task<ActionResult<Relationship>> AcceptFriendRequest(Guid userId)
|
|
{
|
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
|
|
|
var relationship = await rels.GetRelationship(userId, currentUser.Id, RelationshipStatus.Pending);
|
|
if (relationship is null) return NotFound("Friend request was not found.");
|
|
|
|
try
|
|
{
|
|
relationship = await rels.AcceptFriendRelationship(relationship);
|
|
return relationship;
|
|
}
|
|
catch (InvalidOperationException err)
|
|
{
|
|
return BadRequest(err.Message);
|
|
}
|
|
}
|
|
|
|
[HttpPost("{userId:guid}/friends/decline")]
|
|
[Authorize]
|
|
public async Task<ActionResult<Relationship>> DeclineFriendRequest(Guid userId)
|
|
{
|
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
|
|
|
var relationship = await rels.GetRelationship(userId, currentUser.Id, RelationshipStatus.Pending);
|
|
if (relationship is null) return NotFound("Friend request was not found.");
|
|
|
|
try
|
|
{
|
|
relationship = await rels.AcceptFriendRelationship(relationship, status: RelationshipStatus.Blocked);
|
|
return relationship;
|
|
}
|
|
catch (InvalidOperationException err)
|
|
{
|
|
return BadRequest(err.Message);
|
|
}
|
|
}
|
|
|
|
[HttpPost("{userId:guid}/block")]
|
|
[Authorize]
|
|
public async Task<ActionResult<Relationship>> BlockUser(Guid userId)
|
|
{
|
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
|
|
|
var relatedUser = await db.Accounts.FindAsync(userId);
|
|
if (relatedUser is null) return NotFound("Account was not found.");
|
|
|
|
try
|
|
{
|
|
var relationship = await rels.BlockAccount(currentUser, relatedUser);
|
|
return relationship;
|
|
}
|
|
catch (InvalidOperationException err)
|
|
{
|
|
return BadRequest(err.Message);
|
|
}
|
|
}
|
|
} |