Skip to content

Commit

Permalink
feat: upload avatar & cover of profiles
Browse files Browse the repository at this point in the history
  • Loading branch information
LeDuyNhan1201 committed Dec 8, 2024
1 parent 8ed3c8c commit ac83929
Show file tree
Hide file tree
Showing 11 changed files with 198 additions and 113 deletions.
37 changes: 0 additions & 37 deletions Comment.Presentation/Controllers/WeatherForecastController.cs

This file was deleted.

9 changes: 9 additions & 0 deletions Profile.Application/DTOs/Requests/UplodaPhotoRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace InfinityNetServer.Services.Profile.Application.DTOs.Requests
{
public sealed record UplodaPhotoRequest
{

public string PhotoId { get; set; }

}
}
5 changes: 4 additions & 1 deletion Profile.Application/IServices/IProfileService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using InfinityNetServer.BuildingBlocks.Domain.Enums;
using InfinityNetServer.BuildingBlocks.Application.Contracts;
using InfinityNetServer.BuildingBlocks.Domain.Enums;
using System.Collections.Generic;
using System.Threading.Tasks;

Expand All @@ -19,6 +20,8 @@ public interface IProfileService

public Task<Domain.Entities.Profile> Update(Domain.Entities.Profile profile);

public Task ConfirmSave(string id, string fileMetadataId, bool isAvatar, IMessageBus messageBus);


}
}
7 changes: 6 additions & 1 deletion Profile.Application/Services/PageProfileService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,14 @@ public async Task<PageProfile> Update(PageProfile pageProfile)
PageProfile existedProfile = await GetById(pageProfile.Id.ToString())
?? throw new BaseException(BaseError.PROFILE_NOT_FOUND, StatusCodes.Status404NotFound);

existedProfile.AvatarId = pageProfile.AvatarId;
existedProfile.CoverId = pageProfile.CoverId;
existedProfile.Location = pageProfile.Location;
existedProfile.MobileNumber = pageProfile.MobileNumber;
existedProfile.Status = pageProfile.Status;

existedProfile.Name = pageProfile.Name;
existedProfile.Description = pageProfile.Description;
existedProfile.MobileNumber = pageProfile.MobileNumber;

await _pageProfileRepository.UpdateAsync(existedProfile);

Expand Down
24 changes: 23 additions & 1 deletion Profile.Application/Services/ProfileService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using InfinityNetServer.BuildingBlocks.Application.Exceptions;
using InfinityNetServer.BuildingBlocks.Application.Contracts.Events;
using InfinityNetServer.BuildingBlocks.Application.Contracts;
using InfinityNetServer.BuildingBlocks.Application.Exceptions;
using InfinityNetServer.BuildingBlocks.Domain.Enums;
using InfinityNetServer.Services.Profile.Application.IServices;
using InfinityNetServer.Services.Profile.Domain.Entities;
Expand Down Expand Up @@ -48,5 +50,25 @@ public class ProfileService(
return existedProfile;
}

public async Task ConfirmSave(string id, string fileMetadataId, bool isAvatar, IMessageBus messageBus)
{
Domain.Entities.Profile profile = await GetById(id)
?? throw new BaseException(BaseError.POST_NOT_FOUND, StatusCodes.Status404NotFound);

Guid? fileMetadataGuid = (isAvatar ? profile.AvatarId : profile.CoverId)
?? throw new BaseException(BaseError.FILE_NOT_FOUND, StatusCodes.Status404NotFound);

await messageBus.Publish(new DomainEvent.CreatePhotoMetadataEvent
{
FileMetadataId = fileMetadataGuid.Value,
TempId = Guid.Parse(fileMetadataId),
OwnerId = Guid.Parse(id),
OwnerType = FileOwnerType.Post,
UpdatedAt = DateTime.Now,
UpdatedBy = profile.Id
});

}

}
}
9 changes: 8 additions & 1 deletion Profile.Application/Services/UserProfileService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using InfinityNetServer.BuildingBlocks.Application.Exceptions;
using AutoMapper;
using InfinityNetServer.BuildingBlocks.Application.Exceptions;
using InfinityNetServer.BuildingBlocks.Application.GrpcClients;
using InfinityNetServer.BuildingBlocks.Domain.Specifications;
using InfinityNetServer.BuildingBlocks.Domain.Specifications.CursorPaging;
Expand Down Expand Up @@ -199,6 +200,12 @@ public async Task<UserProfile> Update(UserProfile userProfile)
UserProfile existedProfile = await GetById(userProfile.Id.ToString())
?? throw new BaseException(BaseError.PROFILE_NOT_FOUND, StatusCodes.Status404NotFound);

existedProfile.AvatarId = userProfile.AvatarId;
existedProfile.CoverId = userProfile.CoverId;
existedProfile.Location = userProfile.Location;
existedProfile.MobileNumber = userProfile.MobileNumber;
existedProfile.Status = userProfile.Status;

existedProfile.FirstName = userProfile.FirstName;
existedProfile.LastName = userProfile.LastName;
existedProfile.Username = userProfile.Username;
Expand Down
4 changes: 2 additions & 2 deletions Profile.Presentation/Controllers/PageProfileController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ public async Task<IActionResult> UpdateProfile([FromBody] UpdatePageProfileReque

return Ok(new
{
Message = localizer["Message.ProfileUpdatedSuccess", request.Name],
User = pageProfile
Message = localizer["Message.ProfileUpdatedSuccess", request.Name].ToString(),
User = mapper.Map<PageProfileResponse>(pageProfile)
});
}

Expand Down
67 changes: 0 additions & 67 deletions Profile.Presentation/Controllers/ProfileActionController.cs

This file was deleted.

136 changes: 136 additions & 0 deletions Profile.Presentation/Controllers/ProfileController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
using AutoMapper;
using InfinityNetServer.BuildingBlocks.Application.Contracts;
using InfinityNetServer.BuildingBlocks.Application.DTOs.Responses.Profile;
using InfinityNetServer.BuildingBlocks.Application.Exceptions;
using InfinityNetServer.BuildingBlocks.Application.IServices;
using InfinityNetServer.BuildingBlocks.Presentation.Controllers;
using InfinityNetServer.Services.Profile.Application;
using InfinityNetServer.Services.Profile.Application.DTOs.Requests;
using InfinityNetServer.Services.Profile.Application.Exceptions;
using InfinityNetServer.Services.Profile.Application.IServices;
using InfinityNetServer.Services.Profile.Domain.Enums;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace InfinityNetServer.Services.Profile.Presentation.Controllers
{
[Tags("Profile APIs")]
[ApiController]
public class ProfileController(
IAuthenticatedUserService authenticatedUserService,
IStringLocalizer<ProfileSharedResource> localizer,
ILogger<ProfileController> logger,
IMapper mapper,
IMessageBus messageBus,
IProfileService profileService) : BaseApiController(authenticatedUserService)
{


[Authorize]
[EndpointDescription("Retrieve page profile")]
[ProducesResponseType(typeof(UserProfileResponse), StatusCodes.Status200OK)]
[Authorize]
[HttpGet("{id}/actions")]
public IActionResult GetProfileActions(string id)
{
logger.LogInformation("Retrieve user profile");

Guid currentUserId = GetCurrentProfileId != null ? GetCurrentProfileId().Value
: throw new BaseException(BaseError.PROFILE_NOT_FOUND, StatusCodes.Status404NotFound);

Guid.TryParse(id, out Guid profileId);

bool isMe = currentUserId == profileId;

IDictionary<string, bool> actions = new Dictionary<string, bool>
{
{ ProfileActions.ProfileAvatarUpload.ToString(), isMe },
{ ProfileActions.ProfileCoverPhotoUpload.ToString(), isMe },
{ ProfileActions.ProfileAvatarDelete.ToString(), isMe },
{ ProfileActions.ProfileCoverPhotoDelete.ToString(), isMe },
{ ProfileActions.ProfileDetailsUpdate.ToString(), isMe },
{ ProfileActions.ProfileCreate.ToString(), isMe },
{ ProfileActions.ProfileDelete.ToString(), isMe },
{ ProfileActions.ProfileStatusLock.ToString(), !isMe },
{ ProfileActions.ProfileActivityLog.ToString(), isMe },
{ ProfileActions.ProfilePostCreate.ToString(), isMe },
{ ProfileActions.ProfilePostSearch.ToString(), isMe },
{ ProfileActions.ProfileReport.ToString(), !isMe }
};


return Ok(actions);
}

[Authorize]
[EndpointDescription("Upload profile avatar")]
[ProducesResponseType(StatusCodes.Status200OK)]
[HttpPost("avatar")]
public async Task<IActionResult> UploadAvatar([FromBody] UplodaPhotoRequest avatar)
{

Guid profileId = GetCurrentProfileId()
?? throw new BaseException(BaseError.PROFILE_NOT_FOUND, StatusCodes.Status404NotFound);

Domain.Entities.Profile profile = await profileService.GetById(profileId.ToString())
?? throw new BaseException(BaseError.PROFILE_NOT_FOUND, StatusCodes.Status404NotFound);

try
{
profile.AvatarId = Guid.Parse(avatar.PhotoId);
profile = await profileService.Update(profile);
await profileService.ConfirmSave(profile.Id.ToString(), profile.AvatarId.ToString(), false, messageBus);
}
catch (Exception ex)
{
logger.LogError(ex, "Caused by: {Message}", ex.Message);
throw new ProfileException(ProfileError.UPDATE_PROFILE_FAILED, StatusCodes.Status422UnprocessableEntity);
}

return Ok(new
{
Message = localizer["Message.ProfileUpdatedSuccess", profile.Id].ToString(),
Profile = mapper.Map<BaseProfileResponse>(profile)
});
}

[Authorize]
[EndpointDescription("Upload profile cover")]
[ProducesResponseType(StatusCodes.Status200OK)]
[HttpPost("cover")]
public async Task<IActionResult> UploadCover([FromBody] UplodaPhotoRequest request)
{

Guid profileId = GetCurrentProfileId()
?? throw new BaseException(BaseError.PROFILE_NOT_FOUND, StatusCodes.Status404NotFound);

Domain.Entities.Profile profile = await profileService.GetById(profileId.ToString())
?? throw new BaseException(BaseError.PROFILE_NOT_FOUND, StatusCodes.Status404NotFound);

try
{
profile.CoverId = Guid.Parse(request.PhotoId);
profile = await profileService.Update(profile);
await profileService.ConfirmSave(profile.Id.ToString(), profile.CoverId.ToString(), false, messageBus);
}
catch (Exception ex)
{
logger.LogError(ex, "Caused by: {Message}", ex.Message);
throw new ProfileException(ProfileError.UPDATE_PROFILE_FAILED, StatusCodes.Status422UnprocessableEntity);
}

return Ok(new
{
Message = localizer["Message.ProfileUpdatedSuccess", profile.Id].ToString(),
Profile = mapper.Map<BaseProfileResponse>(profile)
});
}

}
}
4 changes: 2 additions & 2 deletions Profile.Presentation/Controllers/UserProfileController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ public async Task<IActionResult> UpdateProfile([FromBody] UpdateUserProfileReque

return Ok(new
{
Message = localizer["Message.ProfileUpdatedSuccess", request.Username],
User = userProfile
Message = localizer["Message.ProfileUpdatedSuccess", request.Username].ToString(),
User = mapper.Map<UserProfileResponse>(userProfile)
});
}

Expand Down
9 changes: 8 additions & 1 deletion Profile.Presentation/Mappers/ProfileMapper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using InfinityNetServer.BuildingBlocks.Application.DTOs.Responses.File;
using InfinityNetServer.BuildingBlocks.Application.DTOs.Requests;
using InfinityNetServer.BuildingBlocks.Application.DTOs.Responses.File;
using InfinityNetServer.BuildingBlocks.Application.DTOs.Responses.Profile;
using InfinityNetServer.Services.Profile.Application.DTOs.Requests;
using InfinityNetServer.Services.Profile.Domain.Entities;
Expand Down Expand Up @@ -98,6 +99,12 @@ public ProfileMapper()
});

// DTO -> Entity
CreateMap<BaseProfileRequest, Domain.Entities.Profile>();

CreateMap<UpdateUserProfileRequest, Domain.Entities.Profile>();

CreateMap<UpdatePageProfileRequest, Domain.Entities.Profile>();

CreateMap<UpdateUserProfileRequest, UserProfile>();

CreateMap<UpdatePageProfileRequest, PageProfile>();
Expand Down

0 comments on commit ac83929

Please sign in to comment.