Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c874f7b797 |
@@ -6,7 +6,7 @@ on:
|
|||||||
- main
|
- main
|
||||||
|
|
||||||
env:
|
env:
|
||||||
VERSION: 1.9.6
|
VERSION: 1.9.7
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# ЧАСТЬ 1: Собираем образы и кладем в Gitea (чтобы делиться с ребятами)
|
# ЧАСТЬ 1: Собираем образы и кладем в Gitea (чтобы делиться с ребятами)
|
||||||
|
|||||||
BIN
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>1.9.6</Version>
|
<Version>1.9.7</Version>
|
||||||
<TargetFramework>net10.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<LangVersion>preview</LangVersion>
|
<LangVersion>preview</LangVersion>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
|||||||
+2
-2
@@ -17,7 +17,7 @@ services:
|
|||||||
retries: 10
|
retries: 10
|
||||||
|
|
||||||
bot:
|
bot:
|
||||||
image: git.codeanddice.ru/toutsu/gmrelay-bot:1.9.6
|
image: git.codeanddice.ru/toutsu/gmrelay-bot:1.9.7
|
||||||
restart: always
|
restart: always
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
db:
|
||||||
@@ -30,7 +30,7 @@ services:
|
|||||||
- gmrelay
|
- gmrelay
|
||||||
|
|
||||||
web:
|
web:
|
||||||
image: git.codeanddice.ru/toutsu/gmrelay-web:1.9.6
|
image: git.codeanddice.ru/toutsu/gmrelay-web:1.9.7
|
||||||
restart: always
|
restart: always
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
db:
|
||||||
|
|||||||
@@ -106,13 +106,13 @@ public sealed class CancelSessionHandler(
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await bot.EditMessageText(
|
await BatchMessageEditor.EditBatchMessageAsync(
|
||||||
|
bot,
|
||||||
chatId: command.ChatId,
|
chatId: command.ChatId,
|
||||||
messageId: session.BatchMessageId ?? command.MessageId,
|
messageId: session.BatchMessageId ?? command.MessageId,
|
||||||
text: renderResult.Text,
|
text: renderResult.Text,
|
||||||
parseMode: Telegram.Bot.Types.Enums.ParseMode.Html,
|
|
||||||
replyMarkup: renderResult.Markup,
|
replyMarkup: renderResult.Markup,
|
||||||
cancellationToken: ct);
|
ct);
|
||||||
|
|
||||||
await bot.AnswerCallbackQuery(command.CallbackQueryId, "Сессия отменена!", cancellationToken: ct);
|
await bot.AnswerCallbackQuery(command.CallbackQueryId, "Сессия отменена!", cancellationToken: ct);
|
||||||
|
|
||||||
|
|||||||
@@ -185,31 +185,63 @@ public sealed class CreateSessionHandler(
|
|||||||
|
|
||||||
var renderResult = SessionBatchRenderer.Render(title, sessions, Array.Empty<ParticipantBatchDto>());
|
var renderResult = SessionBatchRenderer.Render(title, sessions, Array.Empty<ParticipantBatchDto>());
|
||||||
|
|
||||||
if (imageReference is not null)
|
Message batchMessage;
|
||||||
|
|
||||||
|
if (imageReference is not null && renderResult.Text.Length <= 1024)
|
||||||
{
|
{
|
||||||
|
// Картинка + расписание умещаются в одном Telegram-фото с подписью
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await botClient.SendPhoto(
|
batchMessage = await botClient.SendPhoto(
|
||||||
chatId: chatId,
|
chatId: chatId,
|
||||||
messageThreadId: messageThreadId,
|
messageThreadId: messageThreadId,
|
||||||
photo: InputFile.FromString(imageReference),
|
photo: InputFile.FromString(imageReference),
|
||||||
caption: $"🎲 {System.Net.WebUtility.HtmlEncode(title)}",
|
caption: renderResult.Text,
|
||||||
parseMode: Telegram.Bot.Types.Enums.ParseMode.Html,
|
parseMode: Telegram.Bot.Types.Enums.ParseMode.Html,
|
||||||
|
replyMarkup: renderResult.Markup,
|
||||||
cancellationToken: cancellationToken);
|
cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.LogWarning(ex, "Не удалось отправить картинку для батча {BatchId}", batchId);
|
logger.LogWarning(ex, "Не удалось отправить картинку для батча {BatchId}, отправляем текстом", batchId);
|
||||||
|
batchMessage = await botClient.SendMessage(
|
||||||
|
chatId: chatId,
|
||||||
|
messageThreadId: messageThreadId,
|
||||||
|
text: renderResult.Text,
|
||||||
|
parseMode: Telegram.Bot.Types.Enums.ParseMode.Html,
|
||||||
|
replyMarkup: renderResult.Markup,
|
||||||
|
cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Текст слишком длинный для caption — fallback на два сообщения
|
||||||
|
if (imageReference is not null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await botClient.SendPhoto(
|
||||||
|
chatId: chatId,
|
||||||
|
messageThreadId: messageThreadId,
|
||||||
|
photo: InputFile.FromString(imageReference),
|
||||||
|
caption: $"🎲 {System.Net.WebUtility.HtmlEncode(title)}",
|
||||||
|
parseMode: Telegram.Bot.Types.Enums.ParseMode.Html,
|
||||||
|
cancellationToken: cancellationToken);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogWarning(ex, "Не удалось отправить картинку для батча {BatchId}", batchId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var batchMessage = await botClient.SendMessage(
|
batchMessage = await botClient.SendMessage(
|
||||||
chatId: chatId,
|
chatId: chatId,
|
||||||
messageThreadId: messageThreadId,
|
messageThreadId: messageThreadId,
|
||||||
text: renderResult.Text,
|
text: renderResult.Text,
|
||||||
parseMode: Telegram.Bot.Types.Enums.ParseMode.Html,
|
parseMode: Telegram.Bot.Types.Enums.ParseMode.Html,
|
||||||
replyMarkup: renderResult.Markup,
|
replyMarkup: renderResult.Markup,
|
||||||
cancellationToken: cancellationToken);
|
cancellationToken: cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
await connection.ExecuteAsync(
|
await connection.ExecuteAsync(
|
||||||
"UPDATE sessions SET batch_message_id = @MsgId WHERE batch_id = @BatchId",
|
"UPDATE sessions SET batch_message_id = @MsgId WHERE batch_id = @BatchId",
|
||||||
|
|||||||
@@ -138,13 +138,13 @@ public sealed class JoinSessionHandler(
|
|||||||
// 4. Перерисовываем сообщение
|
// 4. Перерисовываем сообщение
|
||||||
var renderResult = SessionBatchRenderer.Render(batchInfo.Title, batchSessions.ToList(), batchParticipants.ToList());
|
var renderResult = SessionBatchRenderer.Render(batchInfo.Title, batchSessions.ToList(), batchParticipants.ToList());
|
||||||
|
|
||||||
await bot.EditMessageText(
|
await BatchMessageEditor.EditBatchMessageAsync(
|
||||||
|
bot,
|
||||||
chatId: command.ChatId,
|
chatId: command.ChatId,
|
||||||
messageId: command.MessageId,
|
messageId: command.MessageId,
|
||||||
text: renderResult.Text,
|
text: renderResult.Text,
|
||||||
parseMode: Telegram.Bot.Types.Enums.ParseMode.Html,
|
|
||||||
replyMarkup: renderResult.Markup,
|
replyMarkup: renderResult.Markup,
|
||||||
cancellationToken: ct);
|
ct);
|
||||||
|
|
||||||
var callbackText = registrationStatus == ParticipantRegistrationStatus.Waitlisted
|
var callbackText = registrationStatus == ParticipantRegistrationStatus.Waitlisted
|
||||||
? "Основной состав заполнен. Вы добавлены в лист ожидания."
|
? "Основной состав заполнен. Вы добавлены в лист ожидания."
|
||||||
|
|||||||
@@ -184,13 +184,13 @@ public sealed class LeaveSessionHandler(
|
|||||||
|
|
||||||
var renderResult = SessionBatchRenderer.Render(session.Title, batchSessions, batchParticipants);
|
var renderResult = SessionBatchRenderer.Render(session.Title, batchSessions, batchParticipants);
|
||||||
|
|
||||||
await bot.EditMessageText(
|
await BatchMessageEditor.EditBatchMessageAsync(
|
||||||
|
bot,
|
||||||
chatId: command.ChatId,
|
chatId: command.ChatId,
|
||||||
messageId: command.MessageId,
|
messageId: command.MessageId,
|
||||||
text: renderResult.Text,
|
text: renderResult.Text,
|
||||||
parseMode: Telegram.Bot.Types.Enums.ParseMode.Html,
|
|
||||||
replyMarkup: renderResult.Markup,
|
replyMarkup: renderResult.Markup,
|
||||||
cancellationToken: ct);
|
ct);
|
||||||
|
|
||||||
var callbackText = participant.RegistrationStatus == ParticipantRegistrationStatus.Waitlisted
|
var callbackText = participant.RegistrationStatus == ParticipantRegistrationStatus.Waitlisted
|
||||||
? "Вы удалены из листа ожидания."
|
? "Вы удалены из листа ожидания."
|
||||||
|
|||||||
@@ -164,13 +164,13 @@ public sealed class PromoteWaitlistedPlayerHandler(
|
|||||||
|
|
||||||
var renderResult = SessionBatchRenderer.Render(session.Title, batchSessions, batchParticipants);
|
var renderResult = SessionBatchRenderer.Render(session.Title, batchSessions, batchParticipants);
|
||||||
|
|
||||||
await bot.EditMessageText(
|
await BatchMessageEditor.EditBatchMessageAsync(
|
||||||
|
bot,
|
||||||
chatId: command.ChatId,
|
chatId: command.ChatId,
|
||||||
messageId: session.BatchMessageId ?? command.MessageId,
|
messageId: session.BatchMessageId ?? command.MessageId,
|
||||||
text: renderResult.Text,
|
text: renderResult.Text,
|
||||||
parseMode: Telegram.Bot.Types.Enums.ParseMode.Html,
|
|
||||||
replyMarkup: renderResult.Markup,
|
replyMarkup: renderResult.Markup,
|
||||||
cancellationToken: ct);
|
ct);
|
||||||
|
|
||||||
await bot.AnswerCallbackQuery(command.CallbackQueryId, $"{promoted.DisplayName} переведен(а) в основной состав.", cancellationToken: ct);
|
await bot.AnswerCallbackQuery(command.CallbackQueryId, $"{promoted.DisplayName} переведен(а) в основной состав.", cancellationToken: ct);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -378,13 +378,13 @@ public sealed class HandleRescheduleTimeInputHandler(
|
|||||||
var renderResult = SessionBatchRenderer.Render(
|
var renderResult = SessionBatchRenderer.Render(
|
||||||
proposal.Title, batchSessions, batchParticipants);
|
proposal.Title, batchSessions, batchParticipants);
|
||||||
|
|
||||||
await bot.EditMessageText(
|
await BatchMessageEditor.EditBatchMessageAsync(
|
||||||
|
bot,
|
||||||
chatId: proposal.TelegramChatId,
|
chatId: proposal.TelegramChatId,
|
||||||
messageId: proposal.BatchMessageId.Value,
|
messageId: proposal.BatchMessageId.Value,
|
||||||
text: renderResult.Text,
|
text: renderResult.Text,
|
||||||
parseMode: Telegram.Bot.Types.Enums.ParseMode.Html,
|
|
||||||
replyMarkup: renderResult.Markup,
|
replyMarkup: renderResult.Markup,
|
||||||
cancellationToken: ct);
|
ct);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
+3
-3
@@ -306,13 +306,13 @@ public sealed class RescheduleVotingDeadlineService(
|
|||||||
{
|
{
|
||||||
var renderResult = SessionBatchRenderer.Render(proposal.Title, batchSessions, batchParticipants);
|
var renderResult = SessionBatchRenderer.Render(proposal.Title, batchSessions, batchParticipants);
|
||||||
|
|
||||||
await bot.EditMessageText(
|
await BatchMessageEditor.EditBatchMessageAsync(
|
||||||
|
bot,
|
||||||
chatId: proposal.TelegramChatId,
|
chatId: proposal.TelegramChatId,
|
||||||
messageId: proposal.BatchMessageId.Value,
|
messageId: proposal.BatchMessageId.Value,
|
||||||
text: renderResult.Text,
|
text: renderResult.Text,
|
||||||
parseMode: ParseMode.Html,
|
|
||||||
replyMarkup: renderResult.Markup,
|
replyMarkup: renderResult.Markup,
|
||||||
cancellationToken: ct);
|
ct);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
using Telegram.Bot;
|
||||||
|
using Telegram.Bot.Types.Enums;
|
||||||
|
using Telegram.Bot.Types.ReplyMarkups;
|
||||||
|
|
||||||
|
namespace GmRelay.Shared.Rendering;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles editing batch messages that may be either text or photo messages.
|
||||||
|
/// When the batch was created with SendPhoto (image + caption), we need
|
||||||
|
/// EditMessageCaption instead of EditMessageText.
|
||||||
|
/// </summary>
|
||||||
|
public static class BatchMessageEditor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Edits a batch message, automatically detecting whether it is a text or photo message.
|
||||||
|
/// Tries EditMessageText first; on failure falls back to EditMessageCaption.
|
||||||
|
/// </summary>
|
||||||
|
public static async Task EditBatchMessageAsync(
|
||||||
|
ITelegramBotClient bot,
|
||||||
|
long chatId,
|
||||||
|
int messageId,
|
||||||
|
string text,
|
||||||
|
InlineKeyboardMarkup? replyMarkup,
|
||||||
|
CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await bot.EditMessageText(
|
||||||
|
chatId: chatId,
|
||||||
|
messageId: messageId,
|
||||||
|
text: text,
|
||||||
|
parseMode: ParseMode.Html,
|
||||||
|
replyMarkup: replyMarkup,
|
||||||
|
cancellationToken: ct);
|
||||||
|
}
|
||||||
|
catch (Telegram.Bot.Exceptions.ApiRequestException ex)
|
||||||
|
when (ex.Message.Contains("there is no text in the message", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// The batch message is a photo — use EditMessageCaption instead.
|
||||||
|
// Caption is limited to 1024 chars; if text exceeds that, truncate gracefully.
|
||||||
|
var caption = text.Length <= 1024 ? text : text[..1021] + "...";
|
||||||
|
await bot.EditMessageCaption(
|
||||||
|
chatId: chatId,
|
||||||
|
messageId: messageId,
|
||||||
|
caption: caption,
|
||||||
|
parseMode: ParseMode.Html,
|
||||||
|
replyMarkup: replyMarkup,
|
||||||
|
cancellationToken: ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1048,11 +1048,11 @@ public sealed class SessionService(
|
|||||||
|
|
||||||
var renderResult = SessionBatchRenderer.Render(title, sessions, participants);
|
var renderResult = SessionBatchRenderer.Render(title, sessions, participants);
|
||||||
|
|
||||||
await bot.EditMessageText(
|
await BatchMessageEditor.EditBatchMessageAsync(
|
||||||
|
bot,
|
||||||
chatId: chatId,
|
chatId: chatId,
|
||||||
messageId: messageId,
|
messageId: messageId,
|
||||||
text: renderResult.Text,
|
text: renderResult.Text,
|
||||||
parseMode: Telegram.Bot.Types.Enums.ParseMode.Html,
|
|
||||||
replyMarkup: renderResult.Markup);
|
replyMarkup: renderResult.Markup);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
Reference in New Issue
Block a user