86 lines
3.9 KiB
C#
86 lines
3.9 KiB
C#
using GmRelay.Shared.Domain;
|
|
using Telegram.Bot.Types.ReplyMarkups;
|
|
|
|
namespace GmRelay.Shared.Rendering;
|
|
|
|
public sealed record SessionBatchDto(Guid SessionId, DateTime ScheduledAt, string Status, int? MaxPlayers);
|
|
public sealed record ParticipantBatchDto(Guid SessionId, string DisplayName, string? TelegramUsername, string RegistrationStatus);
|
|
|
|
public static class SessionBatchRenderer
|
|
{
|
|
public static (string Text, InlineKeyboardMarkup Markup) Render(
|
|
string title,
|
|
IReadOnlyList<SessionBatchDto> sessions,
|
|
IReadOnlyList<ParticipantBatchDto> participants)
|
|
{
|
|
var activeSessions = sessions.OrderBy(s => s.ScheduledAt).ToList();
|
|
|
|
var messageText = $"🎲 <b>Новые игры:</b> {System.Net.WebUtility.HtmlEncode(title)}\n\n" +
|
|
$"<b>Расписание:</b>\n\n";
|
|
|
|
var buttons = new List<InlineKeyboardButton[]>();
|
|
|
|
foreach (var session in activeSessions)
|
|
{
|
|
var sessionPlayers = participants
|
|
.Where(p => p.SessionId == session.SessionId && p.RegistrationStatus == ParticipantRegistrationStatus.Active)
|
|
.ToList();
|
|
var waitlistedPlayers = participants
|
|
.Where(p => p.SessionId == session.SessionId && p.RegistrationStatus == ParticipantRegistrationStatus.Waitlisted)
|
|
.ToList();
|
|
|
|
messageText += $"📅 <b>{session.ScheduledAt.FormatMoscow()}</b>\n";
|
|
messageText += session.MaxPlayers.HasValue
|
|
? $"👥 Места: {sessionPlayers.Count}/{session.MaxPlayers.Value}\n"
|
|
: $"👥 Игроки ({sessionPlayers.Count}):\n";
|
|
|
|
if (sessionPlayers.Count > 0)
|
|
{
|
|
messageText += string.Join("\n", sessionPlayers.Select(p => $" 👤 {(p.TelegramUsername != null ? "@" + p.TelegramUsername : p.DisplayName)}")) + "\n";
|
|
}
|
|
else
|
|
{
|
|
messageText += " <i>Пока никто не записался</i>\n";
|
|
}
|
|
|
|
if (waitlistedPlayers.Count > 0)
|
|
{
|
|
messageText += $"⏳ Лист ожидания ({waitlistedPlayers.Count}):\n";
|
|
messageText += string.Join("\n", waitlistedPlayers.Select(p => $" ⏱ {(p.TelegramUsername != null ? "@" + p.TelegramUsername : p.DisplayName)}")) + "\n";
|
|
}
|
|
|
|
if (SessionStatus.IsCancelled(session.Status))
|
|
{
|
|
messageText += "❌ <i>Сессия отменена</i>\n\n";
|
|
}
|
|
else
|
|
{
|
|
messageText += "\n";
|
|
var dateTitle = session.ScheduledAt.FormatMoscowShort();
|
|
buttons.Add(new[]
|
|
{
|
|
InlineKeyboardButton.WithCallbackData(GetJoinButtonText(session, sessionPlayers.Count, dateTitle), $"join_session:{session.SessionId}"),
|
|
InlineKeyboardButton.WithCallbackData($"❌ Отменить {dateTitle} (ГМ)", $"cancel_session:{session.SessionId}"),
|
|
InlineKeyboardButton.WithCallbackData($"⏰ (ГМ)", $"reschedule_session:{session.SessionId}")
|
|
}
|
|
.Concat(SessionCapacityRules.CanPromoteWaitlistedPlayer(session.MaxPlayers, sessionPlayers.Count, waitlistedPlayers.Count)
|
|
? [InlineKeyboardButton.WithCallbackData($"⬆️ Из ожидания {dateTitle} (ГМ)", $"promote_waitlist:{session.SessionId}")]
|
|
: [])
|
|
.ToArray());
|
|
}
|
|
}
|
|
|
|
return (messageText, new InlineKeyboardMarkup(buttons));
|
|
}
|
|
|
|
private static string GetJoinButtonText(SessionBatchDto session, int activePlayers, string dateTitle)
|
|
{
|
|
if (session.MaxPlayers.HasValue && activePlayers >= session.MaxPlayers.Value)
|
|
{
|
|
return $"⏳ В лист ожидания {dateTitle}";
|
|
}
|
|
|
|
return $"✋ На {dateTitle}";
|
|
}
|
|
}
|