Skip to content

Commit

Permalink
End of section 18
Browse files Browse the repository at this point in the history
  • Loading branch information
TryCatchLearn committed Sep 19, 2020
1 parent 011f312 commit 713e2dc
Show file tree
Hide file tree
Showing 26 changed files with 301 additions and 122 deletions.
24 changes: 11 additions & 13 deletions API/Controllers/LikesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,24 @@ namespace API.Controllers
[Authorize]
public class LikesController : BaseApiController
{
private readonly IUserRepository _userRepository;
private readonly ILikesRepository _likesRepository;
public LikesController(IUserRepository userRepository, ILikesRepository likesRepository)
private readonly IUnitOfWork _unitOfWork;
public LikesController(IUnitOfWork unitOfWork)
{
_likesRepository = likesRepository;
_userRepository = userRepository;
_unitOfWork = unitOfWork;
}

[HttpPost("{username}")]
public async Task<ActionResult> AddLike(string username)
{
var sourceUserId = User.GetUserId();
var likedUser = await _userRepository.GetUserByUsernameAsync(username);
var sourceUser = await _likesRepository.GetUserWithLikes(sourceUserId);
var likedUser = await _unitOfWork.UserRepository.GetUserByUsernameAsync(username);
var sourceUser = await _unitOfWork.LikesRepository.GetUserWithLikes(sourceUserId);

if (likedUser == null) return NotFound();

if (sourceUser.UserName == username) return BadRequest("You cannot like yourself");

var userLike = await _likesRepository.GetUserLike(sourceUserId, likedUser.Id);
var userLike = await _unitOfWork.LikesRepository.GetUserLike(sourceUserId, likedUser.Id);

if (userLike != null) return BadRequest("You already like this user");

Expand All @@ -44,18 +42,18 @@ public async Task<ActionResult> AddLike(string username)

sourceUser.LikedUsers.Add(userLike);

if (await _userRepository.SaveAllAsync()) return Ok();
if (await _unitOfWork.Complete()) return Ok();

return BadRequest("Failed to like user");
}

[HttpGet]
public async Task<ActionResult<IEnumerable<LikeDto>>> GetUserLikes([FromQuery]LikesParams likesParams)
public async Task<ActionResult<IEnumerable<LikeDto>>> GetUserLikes([FromQuery] LikesParams likesParams)
{
likesParams.UserId = User.GetUserId();
var users = await _likesRepository.GetUserLikes(likesParams);
var users = await _unitOfWork.LikesRepository.GetUserLikes(likesParams);

Response.AddPaginationHeader(users.CurrentPage,
Response.AddPaginationHeader(users.CurrentPage,
users.PageSize, users.TotalCount, users.TotalPages);

return Ok(users);
Expand Down
33 changes: 11 additions & 22 deletions API/Controllers/MessagesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,57 +14,46 @@ namespace API.Controllers
[Authorize]
public class MessagesController : BaseApiController
{
private readonly IUserRepository _userRepository;
private readonly IMessageRepository _messageRepository;
private readonly IMapper _mapper;
public MessagesController(IUserRepository userRepository, IMessageRepository messageRepository,
IMapper mapper)
private readonly IUnitOfWork _unitOfWork;
public MessagesController(IMapper mapper, IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
_mapper = mapper;
_messageRepository = messageRepository;
_userRepository = userRepository;
}

[HttpGet]
public async Task<ActionResult<IEnumerable<MessageDto>>> GetMessagesForUser([FromQuery]
public async Task<ActionResult<IEnumerable<MessageDto>>> GetMessagesForUser([FromQuery]
MessageParams messageParams)
{
messageParams.Username = User.GetUsername();

var messages = await _messageRepository.GetMessagesForUser(messageParams);
var messages = await _unitOfWork.MessageRepository.GetMessagesForUser(messageParams);

Response.AddPaginationHeader(messages.CurrentPage, messages.PageSize,
Response.AddPaginationHeader(messages.CurrentPage, messages.PageSize,
messages.TotalCount, messages.TotalPages);

return messages;
}

[HttpGet("thread/{username}")]
public async Task<ActionResult<IEnumerable<MessageDto>>> GetMessageThread(string username)
{
var currentUsername = User.GetUsername();

return Ok(await _messageRepository.GetMessageThread(currentUsername, username));
}

[HttpDelete("{id}")]
public async Task<ActionResult> DeleteMessage(int id)
{
var username = User.GetUsername();

var message = await _messageRepository.GetMessage(id);
var message = await _unitOfWork.MessageRepository.GetMessage(id);

if (message.Sender.UserName != username && message.Recipient.UserName != username)
if (message.Sender.UserName != username && message.Recipient.UserName != username)
return Unauthorized();

if (message.Sender.UserName == username) message.SenderDeleted = true;

if (message.Recipient.UserName == username) message.RecipientDeleted = true;

if (message.SenderDeleted && message.RecipientDeleted)
_messageRepository.DeleteMessage(message);
if (message.SenderDeleted && message.RecipientDeleted)
_unitOfWork.MessageRepository.DeleteMessage(message);

if (await _messageRepository.SaveAllAsync()) return Ok();
if (await _unitOfWork.Complete()) return Ok();

return BadRequest("Problem deleting the message");
}
Expand Down
42 changes: 21 additions & 21 deletions API/Controllers/UsersController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,29 @@ namespace API.Controllers
[Authorize]
public class UsersController : BaseApiController
{
private readonly IUserRepository _userRepository;
private readonly IMapper _mapper;
private readonly IPhotoService _photoService;
public UsersController(IUserRepository userRepository, IMapper mapper,
private readonly IUnitOfWork _unitOfWork;
public UsersController(IUnitOfWork unitOfWork, IMapper mapper,
IPhotoService photoService)
{
_unitOfWork = unitOfWork;
_photoService = photoService;
_mapper = mapper;
_userRepository = userRepository;
}

[HttpGet]
public async Task<ActionResult<IEnumerable<MemberDto>>> GetUsers([FromQuery]UserParams userParams)
public async Task<ActionResult<IEnumerable<MemberDto>>> GetUsers([FromQuery] UserParams userParams)
{
var user = await _userRepository.GetUserByUsernameAsync(User.GetUsername());
userParams.CurrentUsername = user.UserName;
var gender = await _unitOfWork.UserRepository.GetUserGender(User.GetUsername());
userParams.CurrentUsername = User.GetUsername();

if (string.IsNullOrEmpty(userParams.Gender))
userParams.Gender = user.Gender == "male" ? "female" : "male";
userParams.Gender = gender == "male" ? "female" : "male";

var users = await _userRepository.GetMembersAsync(userParams);
var users = await _unitOfWork.UserRepository.GetMembersAsync(userParams);

Response.AddPaginationHeader(users.CurrentPage, users.PageSize,
Response.AddPaginationHeader(users.CurrentPage, users.PageSize,
users.TotalCount, users.TotalPages);

return Ok(users);
Expand All @@ -50,28 +50,28 @@ public async Task<ActionResult<IEnumerable<MemberDto>>> GetUsers([FromQuery]User
[HttpGet("{username}", Name = "GetUser")]
public async Task<ActionResult<MemberDto>> GetUser(string username)
{
return await _userRepository.GetMemberAsync(username);
return await _unitOfWork.UserRepository.GetMemberAsync(username);
}

[HttpPut]
public async Task<ActionResult> UpdateUser(MemberUpdateDto memberUpdateDto)
{

var user = await _userRepository.GetUserByUsernameAsync(User.GetUsername());
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername());

_mapper.Map(memberUpdateDto, user);

_userRepository.Update(user);
_unitOfWork.UserRepository.Update(user);

if (await _userRepository.SaveAllAsync()) return NoContent();
if (await _unitOfWork.Complete()) return NoContent();

return BadRequest("Failed to update user");
}

[HttpPost("add-photo")]
public async Task<ActionResult<PhotoDto>> AddPhoto(IFormFile file)
{
var user = await _userRepository.GetUserByUsernameAsync(User.GetUsername());
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername());

var result = await _photoService.AddPhotoAsync(file);

Expand All @@ -90,19 +90,19 @@ public async Task<ActionResult<PhotoDto>> AddPhoto(IFormFile file)

user.Photos.Add(photo);

if (await _userRepository.SaveAllAsync())
if (await _unitOfWork.Complete())
{
return CreatedAtRoute("GetUser", new {username = user.UserName} ,_mapper.Map<PhotoDto>(photo));
return CreatedAtRoute("GetUser", new { username = user.UserName }, _mapper.Map<PhotoDto>(photo));
}


return BadRequest("Problem addding photo");
}

[HttpPut("set-main-photo/{photoId}")]
public async Task<ActionResult> SetMainPhoto(int photoId)
{
var user = await _userRepository.GetUserByUsernameAsync(User.GetUsername());
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername());

var photo = user.Photos.FirstOrDefault(x => x.Id == photoId);

Expand All @@ -112,15 +112,15 @@ public async Task<ActionResult> SetMainPhoto(int photoId)
if (currentMain != null) currentMain.IsMain = false;
photo.IsMain = true;

if (await _userRepository.SaveAllAsync()) return NoContent();
if (await _unitOfWork.Complete()) return NoContent();

return BadRequest("Failed to set main photo");
}

[HttpDelete("delete-photo/{photoId}")]
public async Task<ActionResult> DeletePhoto(int photoId)
{
var user = await _userRepository.GetUserByUsernameAsync(User.GetUsername());
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername());

var photo = user.Photos.FirstOrDefault(x => x.Id == photoId);

Expand All @@ -136,7 +136,7 @@ public async Task<ActionResult> DeletePhoto(int photoId)

user.Photos.Remove(photo);

if (await _userRepository.SaveAllAsync()) return Ok();
if (await _unitOfWork.Complete()) return Ok();

return BadRequest("Failed to delete the photo");
}
Expand Down
7 changes: 7 additions & 0 deletions API/DTOs/MessageDto.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Text.Json.Serialization;

namespace API.DTOs
{
Expand All @@ -14,5 +15,11 @@ public class MessageDto
public string Content { get; set; }
public DateTime? DateRead { get; set; }
public DateTime MessageSent { get; set; }

[JsonIgnore]
public bool SenderDeleted { get; set; }

[JsonIgnore]
public bool RecipientDeleted { get; set; }
}
}
57 changes: 53 additions & 4 deletions API/Data/DataContext.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
using System;
using API.Entities;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

namespace API.Data
{
public class DataContext : IdentityDbContext<AppUser, AppRole, int,
IdentityUserClaim<int>, AppUserRole, IdentityUserLogin<int>,
public class DataContext : IdentityDbContext<AppUser, AppRole, int,
IdentityUserClaim<int>, AppUserRole, IdentityUserLogin<int>,
IdentityRoleClaim<int>, IdentityUserToken<int>>
{
public DataContext(DbContextOptions options) : base(options)
Expand Down Expand Up @@ -41,14 +45,14 @@ protected override void OnModelCreating(ModelBuilder builder)


builder.Entity<UserLike>()
.HasKey(k => new {k.SourceUserId, k.LikedUserId});
.HasKey(k => new { k.SourceUserId, k.LikedUserId });

builder.Entity<UserLike>()
.HasOne(s => s.SourceUser)
.WithMany(l => l.LikedUsers)
.HasForeignKey(s => s.SourceUserId)
.OnDelete(DeleteBehavior.Cascade);

builder.Entity<UserLike>()
.HasOne(s => s.LikedUser)
.WithMany(l => l.LikedByUsers)
Expand All @@ -64,6 +68,51 @@ protected override void OnModelCreating(ModelBuilder builder)
.HasOne(u => u.Sender)
.WithMany(m => m.MessagesSent)
.OnDelete(DeleteBehavior.Restrict);

builder.ApplyUtcDateTimeConverter();
}
}

public static class UtcDateAnnotation
{
private const String IsUtcAnnotation = "IsUtc";
private static readonly ValueConverter<DateTime, DateTime> UtcConverter =
new ValueConverter<DateTime, DateTime>(v => v, v => DateTime.SpecifyKind(v, DateTimeKind.Utc));

private static readonly ValueConverter<DateTime?, DateTime?> UtcNullableConverter =
new ValueConverter<DateTime?, DateTime?>(v => v, v => v == null ? v : DateTime.SpecifyKind(v.Value, DateTimeKind.Utc));

public static PropertyBuilder<TProperty> IsUtc<TProperty>(this PropertyBuilder<TProperty> builder, Boolean isUtc = true) =>
builder.HasAnnotation(IsUtcAnnotation, isUtc);

public static Boolean IsUtc(this IMutableProperty property) =>
((Boolean?)property.FindAnnotation(IsUtcAnnotation)?.Value) ?? true;

/// <summary>
/// Make sure this is called after configuring all your entities.
/// </summary>
public static void ApplyUtcDateTimeConverter(this ModelBuilder builder)
{
foreach (var entityType in builder.Model.GetEntityTypes())
{
foreach (var property in entityType.GetProperties())
{
if (!property.IsUtc())
{
continue;
}

if (property.ClrType == typeof(DateTime))
{
property.SetValueConverter(UtcConverter);
}

if (property.ClrType == typeof(DateTime?))
{
property.SetValueConverter(UtcNullableConverter);
}
}
}
}
}
}
Loading

0 comments on commit 713e2dc

Please sign in to comment.