Files
Swarm/DysonNetwork.Shared/Models/Poll.cs

225 lines
6.9 KiB
C#

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json;
using System.Text.Json.Serialization;
using DysonNetwork.Shared.Proto;
using Google.Protobuf.WellKnownTypes;
using NodaTime;
namespace DysonNetwork.Shared.Models;
public class SnPoll : ModelBase
{
public Guid Id { get; set; } = Guid.NewGuid();
public List<SnPollQuestion> Questions { get; set; } = new();
[MaxLength(1024)] public string? Title { get; set; }
[MaxLength(4096)] public string? Description { get; set; }
public Instant? EndedAt { get; set; }
public bool IsAnonymous { get; set; }
public Guid PublisherId { get; set; }
[JsonIgnore] public SnPublisher? Publisher { get; set; }
public Poll ToProtoValue()
{
var proto = new Poll
{
Id = Id.ToString(),
IsAnonymous = IsAnonymous,
PublisherId = PublisherId.ToString(),
Publisher = Publisher?.ToProtoValue(),
CreatedAt = Timestamp.FromDateTimeOffset(CreatedAt.ToDateTimeOffset()),
UpdatedAt = Timestamp.FromDateTimeOffset(UpdatedAt.ToDateTimeOffset()),
};
if (Title != null)
proto.Title = Title;
if (Description != null)
proto.Description = Description;
if (EndedAt.HasValue)
proto.EndedAt = Timestamp.FromDateTimeOffset(EndedAt.Value.ToDateTimeOffset());
proto.Questions.AddRange(Questions.Select(q => q.ToProtoValue()));
if (DeletedAt.HasValue)
proto.DeletedAt = Timestamp.FromDateTimeOffset(DeletedAt.Value.ToDateTimeOffset());
return proto;
}
public static SnPoll FromProtoValue(Poll proto)
{
var poll = new SnPoll
{
Id = Guid.Parse(proto.Id),
Title = proto.Title != null ? proto.Title : null,
Description = proto.Description != null ? proto.Description : null,
IsAnonymous = proto.IsAnonymous,
PublisherId = Guid.Parse(proto.PublisherId),
Publisher = proto.Publisher != null ? SnPublisher.FromProtoValue(proto.Publisher) : null,
CreatedAt = Instant.FromDateTimeOffset(proto.CreatedAt.ToDateTimeOffset()),
UpdatedAt = Instant.FromDateTimeOffset(proto.UpdatedAt.ToDateTimeOffset()),
};
if (proto.EndedAt != null)
poll.EndedAt = Instant.FromDateTimeOffset(proto.EndedAt.ToDateTimeOffset());
poll.Questions.AddRange(proto.Questions.Select(SnPollQuestion.FromProtoValue));
if (proto.DeletedAt != null)
poll.DeletedAt = Instant.FromDateTimeOffset(proto.DeletedAt.ToDateTimeOffset());
return poll;
}
}
public enum PollQuestionType
{
SingleChoice,
MultipleChoice,
YesNo,
Rating,
FreeText
}
public class SnPollQuestion : ModelBase
{
public Guid Id { get; set; } = Guid.NewGuid();
public PollQuestionType Type { get; set; }
[Column(TypeName = "jsonb")] public List<SnPollOption>? Options { get; set; }
[MaxLength(1024)] public string Title { get; set; } = null!;
[MaxLength(4096)] public string? Description { get; set; }
public int Order { get; set; } = 0;
public bool IsRequired { get; set; }
public Guid PollId { get; set; }
[JsonIgnore] public SnPoll Poll { get; set; } = null!;
public PollQuestion ToProtoValue()
{
var proto = new PollQuestion
{
Id = Id.ToString(),
Type = (Proto.PollQuestionType)((int)Type + 1),
Title = Title,
Order = Order,
IsRequired = IsRequired,
};
if (Description != null)
proto.Description = Description;
if (Options != null)
proto.Options.AddRange(Options.Select(o => o.ToProtoValue()));
return proto;
}
public static SnPollQuestion FromProtoValue(PollQuestion proto)
{
var question = new SnPollQuestion
{
Id = Guid.Parse(proto.Id),
Type = (PollQuestionType)((int)proto.Type - 1),
Title = proto.Title,
Order = proto.Order,
IsRequired = proto.IsRequired,
};
if (proto.Description != null)
question.Description = proto.Description;
if (proto.Options.Count > 0)
question.Options = proto.Options.Select(SnPollOption.FromProtoValue).ToList();
return question;
}
}
public class SnPollOption
{
public Guid Id { get; set; } = Guid.NewGuid();
[Required][MaxLength(1024)] public string Label { get; set; } = null!;
[MaxLength(4096)] public string? Description { get; set; }
public int Order { get; set; } = 0;
public PollOption ToProtoValue()
{
var proto = new PollOption
{
Id = Id.ToString(),
Label = Label,
Order = Order,
};
if (Description != null)
proto.Description = Description;
return proto;
}
public static SnPollOption FromProtoValue(PollOption proto)
{
return new SnPollOption
{
Id = Guid.Parse(proto.Id),
Label = proto.Label,
Description = proto.Description != null ? proto.Description : null,
Order = proto.Order,
};
}
}
public class SnPollAnswer : ModelBase
{
public Guid Id { get; set; } = Guid.NewGuid();
[Column(TypeName = "jsonb")] public Dictionary<string, JsonElement> Answer { get; set; } = null!;
public Guid AccountId { get; set; }
public Guid PollId { get; set; }
[JsonIgnore] public SnPoll? Poll { get; set; }
[NotMapped] public SnAccount? Account { get; set; }
public PollAnswer ToProtoValue()
{
var proto = new PollAnswer
{
Id = Id.ToString(),
Answer = GrpcTypeHelper.ConvertObjectToByteString(Answer),
AccountId = AccountId.ToString(),
PollId = PollId.ToString(),
CreatedAt = Timestamp.FromDateTimeOffset(CreatedAt.ToDateTimeOffset()),
UpdatedAt = Timestamp.FromDateTimeOffset(UpdatedAt.ToDateTimeOffset()),
};
if (DeletedAt.HasValue)
proto.DeletedAt = Timestamp.FromDateTimeOffset(DeletedAt.Value.ToDateTimeOffset());
return proto;
}
public static SnPollAnswer FromProtoValue(PollAnswer proto)
{
var answer = new SnPollAnswer
{
Id = Guid.Parse(proto.Id),
Answer = GrpcTypeHelper.ConvertByteStringToObject<Dictionary<string, JsonElement>>(proto.Answer),
AccountId = Guid.Parse(proto.AccountId),
PollId = Guid.Parse(proto.PollId),
CreatedAt = Instant.FromDateTimeOffset(proto.CreatedAt.ToDateTimeOffset()),
UpdatedAt = Instant.FromDateTimeOffset(proto.UpdatedAt.ToDateTimeOffset()),
};
if (proto.DeletedAt != null)
answer.DeletedAt = Instant.FromDateTimeOffset(proto.DeletedAt.ToDateTimeOffset());
return answer;
}
}