From ac769e656b122ff569c3f1534701b71e00fed586 Mon Sep 17 00:00:00 2001 From: crupest Date: Tue, 27 Oct 2020 19:21:35 +0800 Subject: Split front and back end. --- BackEnd/Timeline/Models/Http/Timeline.cs | 219 +++++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 BackEnd/Timeline/Models/Http/Timeline.cs (limited to 'BackEnd/Timeline/Models/Http/Timeline.cs') diff --git a/BackEnd/Timeline/Models/Http/Timeline.cs b/BackEnd/Timeline/Models/Http/Timeline.cs new file mode 100644 index 00000000..a81b33f5 --- /dev/null +++ b/BackEnd/Timeline/Models/Http/Timeline.cs @@ -0,0 +1,219 @@ +using AutoMapper; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Infrastructure; +using Microsoft.AspNetCore.Mvc.Routing; +using System; +using System.Collections.Generic; +using Timeline.Controllers; + +namespace Timeline.Models.Http +{ + /// + /// Info of post content. + /// + public class TimelinePostContentInfo + { + /// + /// Type of the post content. + /// + public string Type { get; set; } = default!; + /// + /// If post is of text type. This is the text. + /// + public string? Text { get; set; } + /// + /// If post is of image type. This is the image url. + /// + public string? Url { get; set; } + /// + /// If post has data (currently it means it's a image post), this is the data etag. + /// + public string? ETag { get; set; } + } + + /// + /// Info of a post. + /// + public class TimelinePostInfo + { + /// + /// Post id. + /// + public long Id { get; set; } + /// + /// Content of the post. May be null if post is deleted. + /// + public TimelinePostContentInfo? Content { get; set; } + /// + /// True if post is deleted. + /// + public bool Deleted { get; set; } + /// + /// Post time. + /// + public DateTime Time { get; set; } + /// + /// The author. May be null if the user has been deleted. + /// + public UserInfo? Author { get; set; } = default!; + /// + /// Last updated time. + /// + public DateTime LastUpdated { get; set; } = default!; + } + + /// + /// Info of a timeline. + /// + public class TimelineInfo + { + /// + /// Unique id. + /// + public string UniqueId { get; set; } = default!; + /// + /// Title. + /// + public string Title { get; set; } = default!; + /// + /// Name of timeline. + /// + public string Name { get; set; } = default!; + /// + /// Last modified time of timeline name. + /// + public DateTime NameLastModifed { get; set; } = default!; + /// + /// Timeline description. + /// + public string Description { get; set; } = default!; + /// + /// Owner of the timeline. + /// + public UserInfo Owner { get; set; } = default!; + /// + /// Visibility of the timeline. + /// + public TimelineVisibility Visibility { get; set; } +#pragma warning disable CA2227 // Collection properties should be read only + /// + /// Members of timeline. + /// + public List Members { get; set; } = default!; +#pragma warning restore CA2227 // Collection properties should be read only + /// + /// Create time of timeline. + /// + public DateTime CreateTime { get; set; } = default!; + /// + /// Last modified time of timeline. + /// + public DateTime LastModified { get; set; } = default!; + +#pragma warning disable CA1707 // Identifiers should not contain underscores + /// + /// Related links. + /// + public TimelineInfoLinks _links { get; set; } = default!; +#pragma warning restore CA1707 // Identifiers should not contain underscores + } + + /// + /// Related links for timeline. + /// + public class TimelineInfoLinks + { + /// + /// Self. + /// + public string Self { get; set; } = default!; + /// + /// Posts url. + /// + public string Posts { get; set; } = default!; + } + + public class TimelineInfoLinksValueResolver : IValueResolver + { + private readonly IActionContextAccessor _actionContextAccessor; + private readonly IUrlHelperFactory _urlHelperFactory; + + public TimelineInfoLinksValueResolver(IActionContextAccessor actionContextAccessor, IUrlHelperFactory urlHelperFactory) + { + _actionContextAccessor = actionContextAccessor; + _urlHelperFactory = urlHelperFactory; + } + + public TimelineInfoLinks Resolve(Timeline source, TimelineInfo destination, TimelineInfoLinks destMember, ResolutionContext context) + { + var actionContext = _actionContextAccessor.AssertActionContextForUrlFill(); + var urlHelper = _urlHelperFactory.GetUrlHelper(actionContext); + + return new TimelineInfoLinks + { + Self = urlHelper.ActionLink(nameof(TimelineController.TimelineGet), nameof(TimelineController)[0..^nameof(Controller).Length], new { source.Name }), + Posts = urlHelper.ActionLink(nameof(TimelineController.PostListGet), nameof(TimelineController)[0..^nameof(Controller).Length], new { source.Name }) + }; + } + } + + public class TimelinePostContentResolver : IValueResolver + { + private readonly IActionContextAccessor _actionContextAccessor; + private readonly IUrlHelperFactory _urlHelperFactory; + + public TimelinePostContentResolver(IActionContextAccessor actionContextAccessor, IUrlHelperFactory urlHelperFactory) + { + _actionContextAccessor = actionContextAccessor; + _urlHelperFactory = urlHelperFactory; + } + + public TimelinePostContentInfo? Resolve(TimelinePost source, TimelinePostInfo destination, TimelinePostContentInfo? destMember, ResolutionContext context) + { + var actionContext = _actionContextAccessor.AssertActionContextForUrlFill(); + var urlHelper = _urlHelperFactory.GetUrlHelper(actionContext); + + var sourceContent = source.Content; + + if (sourceContent == null) + { + return null; + } + + if (sourceContent is TextTimelinePostContent textContent) + { + return new TimelinePostContentInfo + { + Type = TimelinePostContentTypes.Text, + Text = textContent.Text + }; + } + else if (sourceContent is ImageTimelinePostContent imageContent) + { + return new TimelinePostContentInfo + { + Type = TimelinePostContentTypes.Image, + Url = urlHelper.ActionLink( + action: nameof(TimelineController.PostDataGet), + controller: nameof(TimelineController)[0..^nameof(Controller).Length], + values: new { Name = source.TimelineName, Id = source.Id }), + ETag = $"\"{imageContent.DataTag}\"" + }; + } + else + { + throw new InvalidOperationException(Resources.Models.Http.Exception.UnknownPostContentType); + } + } + } + + public class TimelineInfoAutoMapperProfile : Profile + { + public TimelineInfoAutoMapperProfile() + { + CreateMap().ForMember(u => u._links, opt => opt.MapFrom()); + CreateMap().ForMember(p => p.Content, opt => opt.MapFrom()); + CreateMap(); + } + } +} -- cgit v1.2.3