Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

366 changes: 237 additions & 129 deletions .idea/.idea.Eclipse/.idea/workspace.xml

Large diffs are not rendered by default.

72 changes: 72 additions & 0 deletions Eclipse/Controllers/ContactController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using Eclipse.Middlewares;
using Eclipse.Models;
using Eclipse.Models.Dto;
using Eclipse.Repositories.Interfaces;
using Eclipse.Services.Interfaces;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Eclipse.Controllers;

[Route("api/contact")]
[ApiController]
public class ContactController : ControllerBase
{
private readonly IContactService _contactService;
private readonly IContactRepository _contactRepository;
private readonly string _successMessage = "Success";

public ContactController(IContactService contactService, IContactRepository contactRepository)
{
_contactService = contactService;
_contactRepository = contactRepository;
}
[Authorize]
[HttpGet]
public async Task<ApiResponse<List<ShortContactDto>?>> GetAllContacts([FromQuery] string? sortOrder = null)
{
var userIdClaim = User.FindFirst("UserId")?.Value;
if (userIdClaim == null) throw new UnauthorizedAccessException();

var userId = Guid.Parse(userIdClaim);

List<ShortContactDto>? contacts;

if (!string.IsNullOrWhiteSpace(sortOrder))
{
contacts = await _contactService.SortContactsByLastOnline(userId, sortOrder);
}
else
{
contacts = await _contactService.GetMappedListOfContacts(userId);
}

return new ApiResponse<List<ShortContactDto>?> { Message = "Success", Data = contacts };
}

[Authorize]
[HttpPost]
[Route("{contactId}/add")]
public async Task<ApiResponse<ShortContactDto>> AddContact(Guid contactId)
{
var userIdClaim = User.FindFirst("UserId");
if (userIdClaim is { Value: null }) throw new UnauthorizedAccessException();

var userId = Guid.Parse(userIdClaim.Value);
var newContact = await _contactService.MapResponseOfNewContact(userId, contactId);
return new ApiResponse<ShortContactDto>{ Message = _successMessage, Data = newContact };
}

[Authorize]
[HttpDelete]
[Route("{contactId}/remove")]
public async Task<ApiResponse<object>> RemoveContact(Guid contactId)
{
var userIdClaim = User.FindFirst("UserId");
if (userIdClaim is { Value: null }) throw new UnauthorizedAccessException();

var userId = Guid.Parse(userIdClaim.Value);
await _contactRepository.RemoveFromContacts(userId, contactId);
return new ApiResponse<object>{ Message = _successMessage, Data = null };
}
}
2 changes: 1 addition & 1 deletion Eclipse/Controllers/UserController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public async Task<ApiResponse<UserProfileDto>> GetUserById(Guid userId)

[Authorize]
[HttpPut]
[Route("user/update/{userId:guid}")]
[Route("user/update")]
public async Task<ApiResponse<User>> UpdateUserById(UserProfileDto userProfileDto)
{
var userIdClaim = User.FindFirst("UserId");
Expand Down
1 change: 1 addition & 0 deletions Eclipse/Data/AutoMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ public AutoMapper()
CreateMap<User, RegisterDto>();
CreateMap<User, UserInfoDto>();
CreateMap<User, UserProfileDto>();
CreateMap<Contact, ShortContactDto>();
}
}
1 change: 0 additions & 1 deletion Eclipse/Eclipse.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
</ItemGroup>

<ItemGroup>
<Folder Include="Controllers\"/>
<Folder Include="Migrations\"/>
</ItemGroup>

Expand Down
28 changes: 28 additions & 0 deletions Eclipse/Middlewares/LastSeenUpdateMiddleware.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Security.Claims;
using Eclipse.Repositories.Interfaces;

namespace Eclipse.Middlewares;

public class LastSeenUpdateMiddleware
{
private readonly RequestDelegate _next;

public LastSeenUpdateMiddleware(RequestDelegate next)
{
_next = next;
}

public async Task InvokeAsync(HttpContext context, IUserRepository userRepository)
{
if (context.User.Identity is { IsAuthenticated: true })
{
var userId = context.User.FindFirst("UserId")?.Value;
if (userId != null)
{
await userRepository.UpdateLastSeen(Guid.Parse(userId));
}
}

await _next(context);
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
Username = table.Column<string>(type: "text", nullable: false),
Phone = table.Column<string>(type: "text", nullable: false),
Pfp = table.Column<string>(type: "text", nullable: true),
LastOnline = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
RegisteredAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
},
constraints: table =>
Expand Down
3 changes: 3 additions & 0 deletions Eclipse/Migrations/AppDbContextModelSnapshot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.HasMaxLength(100)
.HasColumnType("character varying(100)");

b.Property<DateTime>("LastOnline")
.HasColumnType("timestamp with time zone");

b.Property<string>("Name")
.IsRequired()
.HasMaxLength(100)
Expand Down
7 changes: 7 additions & 0 deletions Eclipse/Models/Dto/ShortContactDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Eclipse.Models.Dto;

public class ShortContactDto
{
public UserInfoDto User { get; set; }
public UserInfoDto Contact { get; set; }
}
2 changes: 1 addition & 1 deletion Eclipse/Models/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ public class User

public string Phone { get; set; }
public string? Pfp { get; set; }

public DateTime LastOnline { get; set; }
[DataType(DataType.DateTime)] public DateTime RegisteredAt { get; set; }
}
2 changes: 2 additions & 0 deletions Eclipse/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public static void Main(string[] args)
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<IContactRepository, ContactRepository>();
builder.Services.AddScoped<IContactService, ContactService>();
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
Expand Down Expand Up @@ -96,6 +97,7 @@ public static void Main(string[] args)
app.UseAuthorization();

app.UseMiddleware<ErrorHandlingMiddleware>();
app.UseMiddleware<LastSeenUpdateMiddleware>();
app.UseCors("MyPolicy");
app.MapControllers();

Expand Down
2 changes: 2 additions & 0 deletions Eclipse/Repositories/ContactRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public async Task<List<Contact>> AllContactsOfUser(Guid userId)
{
var contacts = await _context.Contacts
.Where(c => c.UserId == userId)
.Include(c => c.User)
.Include(c => c.ContactUser)
.ToListAsync();
if (contacts.Count == 0)
{
Expand Down
1 change: 1 addition & 0 deletions Eclipse/Repositories/Interfaces/IUserRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ public interface IUserRepository
public Task<List<User>> GetAllUsers();
public Task<User> UploadAvatar(Guid userId, string fileName);
public Task<User?> UpdateUser(Guid userId, UserProfileDto userProfileDto);
public Task UpdateLastSeen(Guid userId);
}
16 changes: 12 additions & 4 deletions Eclipse/Repositories/UserRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,22 @@ public async Task<List<User>> GetAllUsers()
}

public async Task<User> UploadAvatar(Guid userId, string fileName)
{
var user = await GetUserById(userId);
if (user == null) return null;
user.Pfp = fileName;
await _context.SaveChangesAsync();
return user;

}

public async Task UpdateLastSeen(Guid userId)
{
var user = await GetUserById(userId);
if (user != null)
{
user.Pfp = fileName;
await _context.SaveChangesAsync();
return user;
await _context.Users.Where(u=> u.Id == userId)
.ExecuteUpdateAsync(s => s.SetProperty(u => u.LastOnline, DateTime.UtcNow));
}
return null;
}
}
45 changes: 45 additions & 0 deletions Eclipse/Services/ContactService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using AutoMapper;
using Eclipse.Models;
using Eclipse.Models.Dto;
using Eclipse.Repositories.Interfaces;
using Eclipse.Services.Interfaces;

namespace Eclipse.Services;

public class ContactService : IContactService
{
private readonly IContactRepository _contactRepository;
private readonly IMapper _mapper;

public ContactService(IContactRepository contactRepository, IMapper mapper)
{
_contactRepository = contactRepository;
_mapper = mapper;
}

public async Task<List<ShortContactDto>?> SortContactsByLastOnline(Guid userId, string sortOrder = "desc")
{
var contacts = await _contactRepository.AllContactsOfUser(userId);
IEnumerable<Contact> sortedContactsQuery = sortOrder
.Equals("asc", StringComparison.CurrentCultureIgnoreCase)
? contacts
.OrderBy(c => c.User.LastOnline)
: contacts
.OrderByDescending(c => c.User.LastOnline);
var sortedContacts = sortedContactsQuery.ToList();
return _mapper.Map<List<ShortContactDto>>(sortedContacts);
}


public async Task<List<ShortContactDto>?> GetMappedListOfContacts(Guid userId)
{
var contacts = await _contactRepository.AllContactsOfUser(userId);
return _mapper.Map<List<ShortContactDto>>(contacts);
}

public async Task<ShortContactDto> MapResponseOfNewContact(Guid userId, Guid contactId)
{
var newContact = await _contactRepository.AddToContacts(userId, contactId);
return _mapper.Map<ShortContactDto>(newContact);
}
}
10 changes: 10 additions & 0 deletions Eclipse/Services/Interfaces/IContactService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Eclipse.Models.Dto;

namespace Eclipse.Services.Interfaces;

public interface IContactService
{
public Task<List<ShortContactDto>?> SortContactsByLastOnline(Guid userId, string sortOrder = "desc");
public Task<List<ShortContactDto>?> GetMappedListOfContacts(Guid userId);
public Task<ShortContactDto> MapResponseOfNewContact(Guid userId, Guid contactId);
}