Skip to content

Commit

Permalink
Add MessageContextBuilder
Browse files Browse the repository at this point in the history
  • Loading branch information
dyatlov-a committed Jan 17, 2024
1 parent 8886b62 commit 1e970f4
Show file tree
Hide file tree
Showing 11 changed files with 260 additions and 223 deletions.
3 changes: 0 additions & 3 deletions src/Inc.TeamAssistant.Appraiser.Model/Common/Point.cs

This file was deleted.

1 change: 1 addition & 0 deletions src/Inc.TeamAssistant.Appraiser.Model/ISwipeService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Inc.TeamAssistant.Appraiser.Model.Common;
using Inc.TeamAssistant.Primitives;

namespace Inc.TeamAssistant.Appraiser.Model;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public async Task<CommandResult> Handle(AddLocationToMapCommand command, Cancell
if (command is null)
throw new ArgumentNullException(nameof(command));

if (!command.MessageContext.Location.HasValue)
if (command.MessageContext.Location is null)
return CommandResult.Empty;

if (command.MessageContext.ChatId == command.MessageContext.PersonId)
Expand All @@ -45,8 +45,8 @@ public async Task<CommandResult> Handle(AddLocationToMapCommand command, Cancell
var location = new LocationOnMap(
command.MessageContext.PersonId,
command.MessageContext.DisplayUsername,
command.MessageContext.Location.Value.Longitude,
command.MessageContext.Location.Value.Latitude,
command.MessageContext.Location.X,
command.MessageContext.Location.Y,
map);

await _locationsRepository.Insert(location, token);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public static IServiceCollection AddConnectorApplication(this IServiceCollection

services
.AddSingleton<CommandFactory>()
.AddSingleton<DialogCommandFactory>()
.AddSingleton<MessageContextBuilder>()
.AddSingleton<DialogContinuation>()
.AddSingleton<TelegramBotMessageHandler>()
.AddHostedService<TelegramBotConnector>()
Expand Down
111 changes: 4 additions & 107 deletions src/Inc.TeamAssistant.Connector.Application/Services/CommandFactory.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using Inc.TeamAssistant.Connector.Application.CommandHandlers.Begin.Contracts;
using Inc.TeamAssistant.Connector.Domain;
using Inc.TeamAssistant.Connector.Model.Commands.LeaveFromTeam;
using Inc.TeamAssistant.Primitives;
using MediatR;
using Telegram.Bot;
Expand All @@ -11,16 +9,16 @@ internal sealed class CommandFactory
{
private readonly IEnumerable<ICommandCreator> _commandCreators;
private readonly DialogContinuation _dialogContinuation;
private readonly IMessageBuilder _messageBuilder;
private readonly DialogCommandFactory _dialogCommandFactory;

public CommandFactory(
IEnumerable<ICommandCreator> commandCreators,
DialogContinuation dialogContinuation,
IMessageBuilder messageBuilder)
DialogCommandFactory dialogCommandFactory)
{
_commandCreators = commandCreators ?? throw new ArgumentNullException(nameof(commandCreators));
_dialogContinuation = dialogContinuation ?? throw new ArgumentNullException(nameof(dialogContinuation));
_messageBuilder = messageBuilder ?? throw new ArgumentNullException(nameof(messageBuilder));
_dialogCommandFactory = dialogCommandFactory ?? throw new ArgumentNullException(nameof(dialogCommandFactory));
}

public async Task<IRequest<CommandResult>?> TryCreate(
Expand Down Expand Up @@ -51,7 +49,7 @@ public CommandFactory(
{
if (dialogState is null && firstStage.Id == stage.Id || dialogState?.CommandState == stage.Value)
{
var command = await TryCreateCommandFromDialog(
var command = await _dialogCommandFactory.TryCreate(
bot,
botCommand.Value,
dialogState?.CommandState,
Expand Down Expand Up @@ -90,105 +88,4 @@ await _dialogContinuation.End(

return null;
}

private async Task<IRequest<CommandResult>?> TryCreateCommandFromDialog(
Bot bot,
string botCommand,
CommandStage? currentStage,
BotCommandStage stage,
MessageContext messageContext)
{
if (bot is null)
throw new ArgumentNullException(nameof(bot));
if (string.IsNullOrWhiteSpace(botCommand))
throw new ArgumentException("Value cannot be null or whitespace.", nameof(botCommand));
if (stage is null)
throw new ArgumentNullException(nameof(stage));
if (messageContext is null)
throw new ArgumentNullException(nameof(messageContext));

var teamSelected = Guid.TryParse(messageContext.Text.TrimStart('/'), out var teamId);

return (botCommand, currentStage, messageContext.Teams.Count, teamSelected) switch
{
("/cancel", _, _, _) => null,
("/new_team", null, _, _)
=> await CreateEnterTextCommand(bot, botCommand, messageContext, teamId: null, stage.DialogMessageId),
("/leave_team", null, 1, _)
=> new LeaveFromTeamCommand(messageContext, messageContext.Teams[0].Id),
("/leave_team", null, > 1, _)
=> await CreateSelectTeamCommand(botCommand, messageContext, allTeams: false),
("/need_review", null, 0, _)
=> throw new ApplicationException($"Teams for user {messageContext.PersonId} was not found."),
("/need_review", null, 1, _)
=> await CreateEnterTextCommand(bot, botCommand, messageContext, messageContext.Teams[0].Id, stage.DialogMessageId),
("/need_review", null, > 1, _)
=> await CreateSelectTeamCommand(botCommand, messageContext, allTeams: true),
("/need_review", CommandStage.SelectTeam, _, true)
=> await CreateEnterTextCommand(bot, botCommand, messageContext, teamId, stage.DialogMessageId),
("/add", null, 0, _)
=> throw new ApplicationException($"Teams for user {messageContext.PersonId} was not found."),
("/add", null, 1, _)
=> await CreateEnterTextCommand(bot, botCommand, messageContext, messageContext.Teams[0].Id, stage.DialogMessageId),
("/add", null, > 1, _)
=> await CreateSelectTeamCommand(botCommand, messageContext, allTeams: true),
("/add", CommandStage.SelectTeam, _, true)
=> await CreateEnterTextCommand(bot, botCommand, messageContext, teamId, stage.DialogMessageId),
_ => null
};
}

private async Task<IRequest<CommandResult>> CreateSelectTeamCommand(
string botCommand,
MessageContext messageContext,
bool allTeams)
{
if (string.IsNullOrWhiteSpace(botCommand))
throw new ArgumentException("Value cannot be null or whitespace.", nameof(botCommand));
if (messageContext is null)
throw new ArgumentNullException(nameof(messageContext));

var notification = NotificationMessage.Create(
messageContext.ChatId,
await _messageBuilder.Build(Messages.Connector_SelectTeam, messageContext.LanguageId));

foreach (var team in messageContext.Teams.Where(t => allTeams || t.UserInTeam))
notification.WithButton(new Button(team.Name, $"/{team.Id:N}"));

return new BeginCommand(
messageContext,
CommandStage.SelectTeam,
TeamContext: null,
botCommand,
notification);
}

private async Task<IRequest<CommandResult>> CreateEnterTextCommand(
Bot bot,
string botCommand,
MessageContext messageContext,
Guid? teamId,
MessageId messageId)
{
if (bot is null)
throw new ArgumentNullException(nameof(bot));
if (string.IsNullOrWhiteSpace(botCommand))
throw new ArgumentException("Value cannot be null or whitespace.", nameof(botCommand));
if (messageContext is null)
throw new ArgumentNullException(nameof(messageContext));
if (messageId is null)
throw new ArgumentNullException(nameof(messageId));

var team = teamId.HasValue ? bot.Teams.Single(t => t.Id == teamId.Value) : null;
var notification = NotificationMessage.Create(
messageContext.ChatId,
await _messageBuilder.Build(messageId, messageContext.LanguageId));

return new BeginCommand(
messageContext,
CommandStage.EnterText,
team is not null ? new CurrentTeamContext(team.Id, team.Properties) : null,
botCommand,
notification);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
using Inc.TeamAssistant.Connector.Application.CommandHandlers.Begin.Contracts;
using Inc.TeamAssistant.Connector.Domain;
using Inc.TeamAssistant.Connector.Model.Commands.LeaveFromTeam;
using Inc.TeamAssistant.Primitives;
using MediatR;

namespace Inc.TeamAssistant.Connector.Application.Services;

internal sealed class DialogCommandFactory
{
private readonly IMessageBuilder _messageBuilder;

public DialogCommandFactory(IMessageBuilder messageBuilder)
{
_messageBuilder = messageBuilder ?? throw new ArgumentNullException(nameof(messageBuilder));
}

public async Task<IRequest<CommandResult>?> TryCreate(
Bot bot,
string botCommand,
CommandStage? currentStage,
BotCommandStage stage,
MessageContext messageContext)
{
if (bot is null)
throw new ArgumentNullException(nameof(bot));
if (string.IsNullOrWhiteSpace(botCommand))
throw new ArgumentException("Value cannot be null or whitespace.", nameof(botCommand));
if (stage is null)
throw new ArgumentNullException(nameof(stage));
if (messageContext is null)
throw new ArgumentNullException(nameof(messageContext));

var teamSelected = Guid.TryParse(messageContext.Text.TrimStart('/'), out var teamId);

return (botCommand, currentStage, messageContext.Teams.Count, teamSelected) switch
{
("/cancel", _, _, _) => null,
("/new_team", null, _, _)
=> await CreateEnterTextCommand(bot, botCommand, messageContext, teamId: null, stage.DialogMessageId),
("/leave_team", null, 1, _)
=> new LeaveFromTeamCommand(messageContext, messageContext.Teams[0].Id),
("/leave_team", null, > 1, _)
=> await CreateSelectTeamCommand(botCommand, messageContext, allTeams: false),
("/need_review", null, 0, _)
=> throw new ApplicationException($"Teams for user {messageContext.PersonId} was not found."),
("/need_review", null, 1, _)
=> await CreateEnterTextCommand(bot, botCommand, messageContext, messageContext.Teams[0].Id, stage.DialogMessageId),
("/need_review", null, > 1, _)
=> await CreateSelectTeamCommand(botCommand, messageContext, allTeams: true),
("/need_review", CommandStage.SelectTeam, _, true)
=> await CreateEnterTextCommand(bot, botCommand, messageContext, teamId, stage.DialogMessageId),
("/add", null, 0, _)
=> throw new ApplicationException($"Teams for user {messageContext.PersonId} was not found."),
("/add", null, 1, _)
=> await CreateEnterTextCommand(bot, botCommand, messageContext, messageContext.Teams[0].Id, stage.DialogMessageId),
("/add", null, > 1, _)
=> await CreateSelectTeamCommand(botCommand, messageContext, allTeams: true),
("/add", CommandStage.SelectTeam, _, true)
=> await CreateEnterTextCommand(bot, botCommand, messageContext, teamId, stage.DialogMessageId),
_ => null
};
}

private async Task<IRequest<CommandResult>> CreateSelectTeamCommand(
string botCommand,
MessageContext messageContext,
bool allTeams)
{
if (string.IsNullOrWhiteSpace(botCommand))
throw new ArgumentException("Value cannot be null or whitespace.", nameof(botCommand));
if (messageContext is null)
throw new ArgumentNullException(nameof(messageContext));

var notification = NotificationMessage.Create(
messageContext.ChatId,
await _messageBuilder.Build(Messages.Connector_SelectTeam, messageContext.LanguageId));

foreach (var team in messageContext.Teams.Where(t => allTeams || t.UserInTeam))
notification.WithButton(new Button(team.Name, $"/{team.Id:N}"));

return new BeginCommand(
messageContext,
CommandStage.SelectTeam,
TeamContext: null,
botCommand,
notification);
}

private async Task<IRequest<CommandResult>> CreateEnterTextCommand(
Bot bot,
string botCommand,
MessageContext messageContext,
Guid? teamId,
MessageId messageId)
{
if (bot is null)
throw new ArgumentNullException(nameof(bot));
if (string.IsNullOrWhiteSpace(botCommand))
throw new ArgumentException("Value cannot be null or whitespace.", nameof(botCommand));
if (messageContext is null)
throw new ArgumentNullException(nameof(messageContext));
if (messageId is null)
throw new ArgumentNullException(nameof(messageId));

var team = teamId.HasValue ? bot.Teams.Single(t => t.Id == teamId.Value) : null;
var notification = NotificationMessage.Create(
messageContext.ChatId,
await _messageBuilder.Build(messageId, messageContext.LanguageId));

return new BeginCommand(
messageContext,
CommandStage.EnterText,
team is not null ? new CurrentTeamContext(team.Id, team.Properties) : null,
botCommand,
notification);
}
}
Loading

0 comments on commit 1e970f4

Please sign in to comment.