// NOTE: duplicated in GmRelay.Web/Services/TelegramSessionBatchRenderer.cs using GmRelay.Shared.Domain; using GmRelay.Shared.Rendering; using Telegram.Bot.Types.ReplyMarkups; namespace GmRelay.Bot.Infrastructure.Telegram; public static class TelegramSessionBatchRenderer { public static (string Text, InlineKeyboardMarkup Markup) Render(SessionBatchViewModel view) { var messageText = $"🎲 Новые игры: {System.Net.WebUtility.HtmlEncode(view.Title)}\n\n" + $"Расписание:\n\n"; var buttons = new List(); foreach (var session in view.Sessions) { messageText += $"📅 {session.ScheduledAt.FormatMoscow()}\n"; messageText += session.MaxPlayers.HasValue ? $"👥 Места: {session.ActivePlayerCount}/{session.MaxPlayers.Value}\n" : $"👥 Игроки ({session.ActivePlayerCount}):\n"; if (!string.IsNullOrEmpty(session.JoinLink)) { messageText += $"🔗 Ссылка на игру\n"; } if (session.ActivePlayers.Count > 0) { messageText += string.Join("\n", session.ActivePlayers.Select(p => $" 👤 {(p.TelegramUsername != null ? "@" + p.TelegramUsername : p.DisplayName)}")) + "\n"; } else { messageText += " Пока никто не записался\n"; } if (session.WaitlistedPlayers.Count > 0) { messageText += $"⏳ Лист ожидания ({session.WaitlistedPlayers.Count}):\n"; messageText += string.Join("\n", session.WaitlistedPlayers.Select(p => $" ⏱ {(p.TelegramUsername != null ? "@" + p.TelegramUsername : p.DisplayName)}")) + "\n"; } if (GmRelay.Shared.Domain.SessionStatus.IsCancelled(session.Status)) { messageText += "❌ Сессия отменена\n\n"; } else { messageText += "\n"; var actionRow = session.AvailableActions .Select(a => InlineKeyboardButton.WithCallbackData(a.Label, $"{a.ActionKey}:{a.SessionId}")) .ToArray(); if (actionRow.Length > 0) buttons.Add(actionRow); } } return (messageText, new InlineKeyboardMarkup(buttons)); } }