implement preset creation

This commit is contained in:
Slavasil 2025-04-21 01:52:47 +03:00
parent 5a072ebda7
commit c8c602c311
3 changed files with 179 additions and 5 deletions

View File

@ -6,6 +6,7 @@ internal class DialogData
public string? inputPictureFilename;
public string? inputTitle;
public UserPreset[]? shownPresets;
public UserPreset incompletePreset;
}
enum DialogState
@ -18,4 +19,8 @@ enum DialogState
Settings,
ViewingPresets,
ChoosingPreset,
CreatingPreset_AwaitingName,
CreatingPreset_AwaitingOutlineColor,
CreatingPreset_AwaitingTitleColor,
CreatingPreset_AwaitingSubtitleColor,
}

View File

@ -1,4 +1,5 @@
using System.Text;
using System.Drawing;
using System.Text;
using Telegram.Bot.Types.ReplyMarkups;
namespace SimpleTGBot;
@ -17,6 +18,12 @@ internal static class Interactions
public const string settingsMessage = "Здесь можно:\n- настроить сохранённые стили";
public const string choosePresetMessage = "Какой пресет сделать активым (цыфра)?";
public const string enterPresetNumberMessage = "Введи номер пресета.";
public const string enterPresetNameMessage = "Назови свой новый пресет.";
public const string enterPresetOutlineColorMessage_head = "Выбери цвет обводки:\n0) оставить без изменений\n";
public const string enterPresetTitleColorMessage_head = "Выбери цвет заголовка:\n0) оставить без изменений\n";
public const string enterPresetSubtitleColorMessage_head = "Выбери цвет подзаголовка:\n0) оставить без изменений\n";
public const string enterPresetColorMessage_tail = "\nИли введи hex-код цвета через #.";
public const string presetCreatedMessage = "Пресет создан!";
static readonly string[] helloWords = ["прив","привет","▶️начать","ку","хай","приветик","превед","привки","хаюхай","здравствуй","здравствуйте","здорово","дарова","дороу","здарова","здорова"];
static readonly string[] cancelWords = ["↩️назад", "назад", "выйти", "отмена", "отменить", "отменяй", "галя", "галина", "стоп"];
@ -25,13 +32,17 @@ internal static class Interactions
public static readonly string backButtonText = "↩️Назад";
public static readonly string gotoPresetsButtonText = "🎨Сохранённые стили";
public static readonly string doneButtonText = "✅Готово";
public static readonly string choosePresetButtonText = "☑️Выбрать активный";
public static readonly string choosePresetButtonText = "☑️Выбрать";
public static readonly string createPresetButtonText = "🔶Создать";
public static readonly Color[] quickSelectColors = [Color.FromArgb(255,255,255,255),Color.FromArgb(255,192,192,192),Color.FromArgb(255,15,216,152),Color.FromArgb(255,85,119,252)];
public static readonly string[] quickSelectColorNames = ["белый", "серый", "зелёный", "голубой"];
public static readonly IReplyMarkup mainReplyMarkup = new ReplyKeyboardMarkup([[new KeyboardButton("▶️Начать")], [new KeyboardButton("⚙️Настройки")]]);
public static readonly IReplyMarkup backButtonReplyMarkup = new ReplyKeyboardMarkup(new KeyboardButton("↩️Назад"));
public static readonly IReplyMarkup resultActionReplyMarkup = new ReplyKeyboardMarkup([new KeyboardButton(doneButtonText)]);
public static readonly IReplyMarkup settingsReplyMarkup = new ReplyKeyboardMarkup([[new KeyboardButton(gotoPresetsButtonText)], [new KeyboardButton(backButtonText)]]);
public static readonly IReplyMarkup presetsReplyMarkup = new ReplyKeyboardMarkup([[new KeyboardButton(choosePresetButtonText)], [new KeyboardButton(backButtonText)]]);
public static readonly IReplyMarkup presetsReplyMarkup = new ReplyKeyboardMarkup([[new KeyboardButton(choosePresetButtonText), new KeyboardButton(createPresetButtonText)], [new KeyboardButton(backButtonText)]]);
static readonly string[] digitEmojis = ["0⃣", "1⃣", "2⃣", "3⃣", "4⃣", "5⃣", "6⃣", "7⃣", "8⃣", "9⃣"];
@ -86,6 +97,42 @@ internal static class Interactions
return msg.ToString();
}
public static string MakeColorPickMessage(int type)
{
StringBuilder msg = new StringBuilder();
msg.Append(type switch
{
0 => enterPresetOutlineColorMessage_head,
1 => enterPresetTitleColorMessage_head,
_ => enterPresetSubtitleColorMessage_head
});
for (int i = 1; i < quickSelectColors.Length; i++)
{
msg.Append($"{i}) {quickSelectColorNames[i - 1]} ({ColorToHex(quickSelectColors[i])})\n");
}
msg.Append(enterPresetColorMessage_tail);
return msg.ToString();
}
public static string ColorToHex(Color color)
{
return "#" + (color.ToArgb() & 0xFFFFFF).ToString("x6");
}
public static bool HexToColor(string hex, out Color color)
{
if (uint.TryParse(hex[1..], out uint c))
{
color = Color.FromArgb((int)(0xFF000000U | c));
return true;
}
else
{
color = default;
return false;
}
}
public static string DigitsToEmoji(string s)
{
StringBuilder sb = new StringBuilder(s.Length * 4);

View File

@ -244,6 +244,12 @@ internal class TelegramBot
dialogData.state = DialogState.ChoosingPreset;
await botClient.SendTextMessageAsync(message.Chat.Id, Interactions.choosePresetMessage, replyMarkup: Interactions.backButtonReplyMarkup);
}
else if (messageText == Interactions.createPresetButtonText)
{
replied = true;
dialogData.state = DialogState.CreatingPreset_AwaitingName;
await botClient.SendTextMessageAsync(message.Chat.Id, Interactions.enterPresetNameMessage, replyMarkup: Interactions.backButtonReplyMarkup, cancellationToken: cancellationToken);
}
}
if (!replied)
{
@ -280,6 +286,97 @@ internal class TelegramBot
}
break;
}
case DialogState.CreatingPreset_AwaitingName:
case DialogState.CreatingPreset_AwaitingOutlineColor:
case DialogState.CreatingPreset_AwaitingTitleColor:
case DialogState.CreatingPreset_AwaitingSubtitleColor:
{
bool replied = false;
if (message.Text is { } messageText)
{
if (messageText == Interactions.backButtonText)
{
replied = true;
await DialogShowPresets(botClient, user, message.Chat.Id, dialogData);
}
else if (dialogData.state == DialogState.CreatingPreset_AwaitingName)
{
replied = true;
dialogData.incompletePreset.Name = messageText;
dialogData.state = DialogState.CreatingPreset_AwaitingOutlineColor;
await botClient.SendTextMessageAsync(message.Chat.Id, Interactions.MakeColorPickMessage(0), replyMarkup: Interactions.backButtonReplyMarkup, cancellationToken: cancellationToken);
}
else
{
System.Drawing.Color color = default;
bool unchanged = false;
if (messageText.StartsWith('#'))
{
if (Interactions.HexToColor(messageText, out color))
{
replied = true;
}
} else
{
if (int.TryParse(messageText, out int colorNumber))
{
if (colorNumber >= 0 && colorNumber <= Interactions.quickSelectColors.Length)
{
if (colorNumber == 0)
{
unchanged = true;
}
else
{
color = Interactions.quickSelectColors[colorNumber - 1];
}
replied = true;
}
}
}
if (replied)
{
if (dialogData.state == DialogState.CreatingPreset_AwaitingOutlineColor)
{
dialogData.incompletePreset.OutlineColor = unchanged ? System.Drawing.Color.FromArgb(255, 255, 255, 255) : color;
dialogData.state = DialogState.CreatingPreset_AwaitingTitleColor;
await botClient.SendTextMessageAsync(message.Chat.Id, Interactions.MakeColorPickMessage(1), replyMarkup: Interactions.backButtonReplyMarkup, cancellationToken: cancellationToken);
}
else if (dialogData.state == DialogState.CreatingPreset_AwaitingTitleColor)
{
dialogData.incompletePreset.TitleColor = unchanged ? System.Drawing.Color.FromArgb(255, 255, 255, 255) : color;
dialogData.state = DialogState.CreatingPreset_AwaitingSubtitleColor;
await botClient.SendTextMessageAsync(message.Chat.Id, Interactions.MakeColorPickMessage(2), replyMarkup: Interactions.backButtonReplyMarkup, cancellationToken: cancellationToken);
}
else if (dialogData.state == DialogState.CreatingPreset_AwaitingSubtitleColor)
{
dialogData.incompletePreset.SubtitleColor = unchanged ? System.Drawing.Color.FromArgb(255, 255, 255, 255) : color;
dialogData.incompletePreset.OwnerId = user.Id;
long id = await AddPresetToDatabase(dialogData.incompletePreset);
logger.Info($"Создан новый пресет стиля для пользователя {user.Id}: {id}");
await botClient.SendTextMessageAsync(message.Chat.Id, Interactions.presetCreatedMessage, replyMarkup: Interactions.backButtonReplyMarkup, cancellationToken: cancellationToken);
await DialogShowPresets(botClient, user, message.Chat.Id, dialogData);
}
}
}
}
if (!replied)
{
if (dialogData.state == DialogState.CreatingPreset_AwaitingName)
await botClient.SendTextMessageAsync(message.Chat.Id, Interactions.enterPresetNameMessage, replyMarkup: Interactions.backButtonReplyMarkup, cancellationToken: cancellationToken);
else
{
int t = dialogData.state switch
{
DialogState.CreatingPreset_AwaitingOutlineColor => 0,
DialogState.CreatingPreset_AwaitingTitleColor => 1,
DialogState.CreatingPreset_AwaitingSubtitleColor => 2,
};
await botClient.SendTextMessageAsync(message.Chat.Id, Interactions.MakeColorPickMessage(t), replyMarkup: Interactions.backButtonReplyMarkup, cancellationToken: cancellationToken);
}
}
break;
}
}
}
@ -329,10 +426,19 @@ internal class TelegramBot
if (subtitle != null)
{
logger.Info($"Генерирую простой демотиватор: [\"{title}\", \"{subtitle}\"]");
DemotivatorStyle style = DemotivatorGen.DefaultStyle();
try
{
ApplyUserPreset(style, await GetActiveUserPreset(message.From!));
}
catch (Exception)
{
logger.Error("Не удалось применить пользовательский стиль");
}
MemoryStream demotivator = DemotivatorGen.MakePictureDemotivator(
dialogData.inputPictureFilename!,
[new DemotivatorText() { Title = title, Subtitle = subtitle }],
DemotivatorGen.DefaultStyle());
style);
dialogData.state = DialogState.ShowingResult;
await botClient.SendPhotoAsync(message.Chat.Id, new InputFile(demotivator, "dem.png"), caption: Interactions.showingResultMessage, replyMarkup: Interactions.resultActionReplyMarkup, cancellationToken: cancellationToken);
demotivator.Dispose();
@ -351,10 +457,19 @@ internal class TelegramBot
string title = dialogData.inputTitle!;
logger.Info($"Генерирую простой демотиватор: [\"{title}\", \"{subtitle}\"]");
DemotivatorStyle style = DemotivatorGen.DefaultStyle();
try
{
ApplyUserPreset(style, await GetActiveUserPreset(message.From!));
}
catch (Exception)
{
logger.Error("Не удалось применить пользовательский стиль");
}
MemoryStream demotivator = DemotivatorGen.MakePictureDemotivator(
dialogData.inputPictureFilename!,
[new DemotivatorText() { Title = title, Subtitle = subtitle }],
DemotivatorGen.DefaultStyle());
style);
dialogData.state = DialogState.ShowingResult;
await botClient.SendPhotoAsync(message.Chat.Id, new InputFile(demotivator, "dem.png"), caption: Interactions.showingResultMessage, replyMarkup: Interactions.resultActionReplyMarkup, cancellationToken: cancellationToken);
demotivator.Dispose();
@ -391,6 +506,13 @@ internal class TelegramBot
await botClient.SendTextMessageAsync(chatId, Interactions.MakePresetListMessage(presets.Select(preset => preset.Name).ToArray(), activePresetIndex), replyMarkup: Interactions.presetsReplyMarkup);
}
void ApplyUserPreset(DemotivatorStyle style, UserPreset preset)
{
style.OutlineColor = preset.OutlineColor;
style.TitleColor = preset.TitleColor;
style.SubtitleColor = preset.SubtitleColor;
}
async Task AddUserToDatabase(User u)
{
var cmd = database.CreateCommand();