fix: reformat using C# rules
This commit is contained in:
@@ -1,21 +1,18 @@
|
||||
using TelegramBotBase.Attributes;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
namespace TelegramBotBase.Form;
|
||||
|
||||
/// <summary>
|
||||
/// A simple prompt dialog with one ok Button
|
||||
/// </summary>
|
||||
[IgnoreState]
|
||||
public class AlertDialog : ConfirmDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// A simple prompt dialog with one ok Button
|
||||
/// </summary>
|
||||
[IgnoreState]
|
||||
public class AlertDialog : ConfirmDialog
|
||||
public AlertDialog(string message, string buttonText) : base(message)
|
||||
{
|
||||
public string ButtonText { get; set; }
|
||||
|
||||
public AlertDialog(string message, string buttonText) : base(message)
|
||||
{
|
||||
Buttons.Add(new ButtonBase(buttonText, "ok"));
|
||||
this.ButtonText = buttonText;
|
||||
|
||||
}
|
||||
|
||||
Buttons.Add(new ButtonBase(buttonText, "ok"));
|
||||
ButtonText = buttonText;
|
||||
}
|
||||
}
|
||||
|
||||
public string ButtonText { get; set; }
|
||||
}
|
||||
@@ -1,113 +1,112 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Args;
|
||||
using TelegramBotBase.Attributes;
|
||||
using TelegramBotBase.Base;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
namespace TelegramBotBase.Form;
|
||||
|
||||
/// <summary>
|
||||
/// A prompt with a lot of buttons
|
||||
/// </summary>
|
||||
[IgnoreState]
|
||||
public class ArrayPromptDialog : FormBase
|
||||
{
|
||||
/// <summary>
|
||||
/// A prompt with a lot of buttons
|
||||
/// </summary>
|
||||
[IgnoreState]
|
||||
public class ArrayPromptDialog : FormBase
|
||||
public ArrayPromptDialog()
|
||||
{
|
||||
/// <summary>
|
||||
/// The message the users sees.
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An additional optional value.
|
||||
/// </summary>
|
||||
public object Tag { get; set; }
|
||||
public ArrayPromptDialog(string message)
|
||||
{
|
||||
Message = message;
|
||||
}
|
||||
|
||||
public ButtonBase[][] Buttons { get; set; }
|
||||
public ArrayPromptDialog(string message, params ButtonBase[][] buttons)
|
||||
{
|
||||
Message = message;
|
||||
Buttons = buttons;
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public Dictionary<string, FormBase> ButtonForms { get; set; } = new Dictionary<string, FormBase>();
|
||||
/// <summary>
|
||||
/// The message the users sees.
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
private static object EvButtonClicked { get; } = new object();
|
||||
/// <summary>
|
||||
/// An additional optional value.
|
||||
/// </summary>
|
||||
public object Tag { get; set; }
|
||||
|
||||
public ArrayPromptDialog()
|
||||
public ButtonBase[][] Buttons { get; set; }
|
||||
|
||||
[Obsolete] public Dictionary<string, FormBase> ButtonForms { get; set; } = new();
|
||||
|
||||
private static object EvButtonClicked { get; } = new();
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
var call = message.GetData<CallbackData>();
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
if (!message.IsAction)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public ArrayPromptDialog(string message)
|
||||
await message.ConfirmAction();
|
||||
|
||||
await message.DeleteMessage();
|
||||
|
||||
var buttons = Buttons.Aggregate((a, b) => a.Union(b).ToArray()).ToList();
|
||||
|
||||
if (call == null)
|
||||
{
|
||||
this.Message = message;
|
||||
return;
|
||||
}
|
||||
|
||||
public ArrayPromptDialog(string message, params ButtonBase[][] buttons)
|
||||
var button = buttons.FirstOrDefault(a => a.Value == call.Value);
|
||||
|
||||
if (button == null)
|
||||
{
|
||||
this.Message = message;
|
||||
this.Buttons = buttons;
|
||||
return;
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
OnButtonClicked(new ButtonClickedEventArgs(button) { Tag = Tag });
|
||||
|
||||
var fb = ButtonForms.ContainsKey(call.Value) ? ButtonForms[call.Value] : null;
|
||||
|
||||
if (fb != null)
|
||||
{
|
||||
var call = message.GetData<CallbackData>();
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
if (!message.IsAction)
|
||||
return;
|
||||
|
||||
await message.ConfirmAction();
|
||||
|
||||
await message.DeleteMessage();
|
||||
|
||||
var buttons = Buttons.Aggregate((a, b) => a.Union(b).ToArray()).ToList();
|
||||
|
||||
if(call==null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var button = buttons.FirstOrDefault(a => a.Value == call.Value);
|
||||
|
||||
if (button == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OnButtonClicked(new ButtonClickedEventArgs(button) { Tag = Tag });
|
||||
|
||||
var fb = ButtonForms.ContainsKey(call.Value) ? ButtonForms[call.Value] : null;
|
||||
|
||||
if (fb != null)
|
||||
{
|
||||
await NavigateTo(fb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
var btn = new ButtonForm();
|
||||
|
||||
foreach(var bl in Buttons)
|
||||
{
|
||||
btn.AddButtonRow(bl.Select(a => new ButtonBase(a.Text, CallbackData.Create("action", a.Value))).ToList());
|
||||
}
|
||||
|
||||
await Device.Send(Message, btn);
|
||||
}
|
||||
|
||||
|
||||
public event EventHandler<ButtonClickedEventArgs> ButtonClicked
|
||||
{
|
||||
add => Events.AddHandler(EvButtonClicked, value);
|
||||
remove => Events.RemoveHandler(EvButtonClicked, value);
|
||||
}
|
||||
|
||||
public void OnButtonClicked(ButtonClickedEventArgs e)
|
||||
{
|
||||
(Events[EvButtonClicked] as EventHandler<ButtonClickedEventArgs>)?.Invoke(this, e);
|
||||
await NavigateTo(fb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
var btn = new ButtonForm();
|
||||
|
||||
foreach (var bl in Buttons)
|
||||
{
|
||||
btn.AddButtonRow(
|
||||
bl.Select(a => new ButtonBase(a.Text, CallbackData.Create("action", a.Value))).ToList());
|
||||
}
|
||||
|
||||
await Device.Send(Message, btn);
|
||||
}
|
||||
|
||||
|
||||
public event EventHandler<ButtonClickedEventArgs> ButtonClicked
|
||||
{
|
||||
add => Events.AddHandler(EvButtonClicked, value);
|
||||
remove => Events.RemoveHandler(EvButtonClicked, value);
|
||||
}
|
||||
|
||||
public void OnButtonClicked(ButtonClickedEventArgs e)
|
||||
{
|
||||
(Events[EvButtonClicked] as EventHandler<ButtonClickedEventArgs>)?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,135 +11,143 @@ using TelegramBotBase.Attributes;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Enums;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
namespace TelegramBotBase.Form;
|
||||
|
||||
/// <summary>
|
||||
/// A form which cleans up old messages sent within
|
||||
/// </summary>
|
||||
public class AutoCleanForm : FormBase
|
||||
{
|
||||
/// <summary>
|
||||
/// A form which cleans up old messages sent within
|
||||
/// </summary>
|
||||
public class AutoCleanForm : FormBase
|
||||
public AutoCleanForm()
|
||||
{
|
||||
[SaveState]
|
||||
public List<int> OldMessages { get; set; }
|
||||
OldMessages = new List<int>();
|
||||
DeleteMode = EDeleteMode.OnEveryCall;
|
||||
DeleteSide = EDeleteSide.BotOnly;
|
||||
|
||||
[SaveState]
|
||||
public EDeleteMode DeleteMode { get; set; }
|
||||
Init += AutoCleanForm_Init;
|
||||
|
||||
[SaveState]
|
||||
public EDeleteSide DeleteSide { get; set; }
|
||||
Closed += AutoCleanForm_Closed;
|
||||
}
|
||||
|
||||
[SaveState] public List<int> OldMessages { get; set; }
|
||||
|
||||
[SaveState] public EDeleteMode DeleteMode { get; set; }
|
||||
|
||||
public AutoCleanForm()
|
||||
[SaveState] public EDeleteSide DeleteSide { get; set; }
|
||||
|
||||
private Task AutoCleanForm_Init(object sender, InitEventArgs e)
|
||||
{
|
||||
if (Device == null)
|
||||
{
|
||||
OldMessages = new List<int>();
|
||||
DeleteMode = EDeleteMode.OnEveryCall;
|
||||
DeleteSide = EDeleteSide.BotOnly;
|
||||
|
||||
Init += AutoCleanForm_Init;
|
||||
|
||||
Closed += AutoCleanForm_Closed;
|
||||
|
||||
}
|
||||
|
||||
private Task AutoCleanForm_Init(object sender, InitEventArgs e)
|
||||
{
|
||||
if (Device == null)
|
||||
return Task.CompletedTask;
|
||||
|
||||
Device.MessageSent += Device_MessageSent;
|
||||
|
||||
Device.MessageReceived += Device_MessageReceived;
|
||||
|
||||
Device.MessageDeleted += Device_MessageDeleted;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void Device_MessageDeleted(object sender, MessageDeletedEventArgs e)
|
||||
Device.MessageSent += Device_MessageSent;
|
||||
|
||||
Device.MessageReceived += Device_MessageReceived;
|
||||
|
||||
Device.MessageDeleted += Device_MessageDeleted;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void Device_MessageDeleted(object sender, MessageDeletedEventArgs e)
|
||||
{
|
||||
if (OldMessages.Contains(e.MessageId))
|
||||
{
|
||||
if (OldMessages.Contains(e.MessageId))
|
||||
OldMessages.Remove(e.MessageId);
|
||||
OldMessages.Remove(e.MessageId);
|
||||
}
|
||||
}
|
||||
|
||||
private void Device_MessageReceived(object sender, MessageReceivedEventArgs e)
|
||||
{
|
||||
if (DeleteSide == EDeleteSide.BotOnly)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
private void Device_MessageReceived(object sender, MessageReceivedEventArgs e)
|
||||
OldMessages.Add(e.Message.MessageId);
|
||||
}
|
||||
|
||||
private Task Device_MessageSent(object sender, MessageSentEventArgs e)
|
||||
{
|
||||
if (DeleteSide == EDeleteSide.UserOnly)
|
||||
{
|
||||
if (DeleteSide == EDeleteSide.BotOnly)
|
||||
return;
|
||||
|
||||
OldMessages.Add(e.Message.MessageId);
|
||||
}
|
||||
|
||||
private Task Device_MessageSent(object sender, MessageSentEventArgs e)
|
||||
{
|
||||
if (DeleteSide == EDeleteSide.UserOnly)
|
||||
return Task.CompletedTask;
|
||||
|
||||
OldMessages.Add(e.Message.MessageId);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public override async Task PreLoad(MessageResult message)
|
||||
{
|
||||
if (DeleteMode != EDeleteMode.OnEveryCall)
|
||||
return;
|
||||
OldMessages.Add(e.Message.MessageId);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
await MessageCleanup();
|
||||
public override async Task PreLoad(MessageResult message)
|
||||
{
|
||||
if (DeleteMode != EDeleteMode.OnEveryCall)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a message to this of removable ones
|
||||
/// </summary>
|
||||
/// <param name="Id"></param>
|
||||
public void AddMessage(Message m)
|
||||
await MessageCleanup();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a message to this of removable ones
|
||||
/// </summary>
|
||||
/// <param name="Id"></param>
|
||||
public void AddMessage(Message m)
|
||||
{
|
||||
OldMessages.Add(m.MessageId);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds a message to this of removable ones
|
||||
/// </summary>
|
||||
/// <param name="Id"></param>
|
||||
public void AddMessage(int messageId)
|
||||
{
|
||||
OldMessages.Add(messageId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Keeps the message by removing it from the list
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
public void LeaveMessage(int id)
|
||||
{
|
||||
OldMessages.Remove(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Keeps the last sent message
|
||||
/// </summary>
|
||||
public void LeaveLastMessage()
|
||||
{
|
||||
if (OldMessages.Count == 0)
|
||||
{
|
||||
OldMessages.Add(m.MessageId);
|
||||
return;
|
||||
}
|
||||
|
||||
OldMessages.RemoveAt(OldMessages.Count - 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a message to this of removable ones
|
||||
/// </summary>
|
||||
/// <param name="Id"></param>
|
||||
public void AddMessage(int messageId)
|
||||
private Task AutoCleanForm_Closed(object sender, EventArgs e)
|
||||
{
|
||||
if (DeleteMode != EDeleteMode.OnLeavingForm)
|
||||
{
|
||||
OldMessages.Add(messageId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Keeps the message by removing it from the list
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
public void LeaveMessage(int id)
|
||||
{
|
||||
OldMessages.Remove(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Keeps the last sent message
|
||||
/// </summary>
|
||||
public void LeaveLastMessage()
|
||||
{
|
||||
if (OldMessages.Count == 0)
|
||||
return;
|
||||
|
||||
OldMessages.RemoveAt(OldMessages.Count - 1);
|
||||
}
|
||||
|
||||
private Task AutoCleanForm_Closed(object sender, EventArgs e)
|
||||
{
|
||||
if (DeleteMode != EDeleteMode.OnLeavingForm)
|
||||
return Task.CompletedTask;
|
||||
|
||||
MessageCleanup().Wait();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleans up all remembered messages.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task MessageCleanup()
|
||||
{
|
||||
var oldMessages = OldMessages.AsEnumerable();
|
||||
MessageCleanup().Wait();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleans up all remembered messages.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task MessageCleanup()
|
||||
{
|
||||
var oldMessages = OldMessages.AsEnumerable();
|
||||
|
||||
#if !NETSTANDARD2_0
|
||||
while (oldMessages.Any())
|
||||
@@ -181,51 +189,51 @@ namespace TelegramBotBase.Form
|
||||
await retryAfterTask;
|
||||
}
|
||||
#else
|
||||
while (oldMessages.Any())
|
||||
while (oldMessages.Any())
|
||||
{
|
||||
using (var cts = new CancellationTokenSource())
|
||||
{
|
||||
using (var cts = new CancellationTokenSource())
|
||||
var deletedMessages = new ConcurrentBag<int>();
|
||||
var parallelQuery = OldMessages.AsParallel()
|
||||
.WithCancellation(cts.Token);
|
||||
Task retryAfterTask = null;
|
||||
try
|
||||
{
|
||||
var deletedMessages = new ConcurrentBag<int>();
|
||||
var parallelQuery = OldMessages.AsParallel()
|
||||
.WithCancellation(cts.Token);
|
||||
Task retryAfterTask = null;
|
||||
try
|
||||
parallelQuery.ForAll(i =>
|
||||
{
|
||||
parallelQuery.ForAll(i =>
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
Device.DeleteMessage(i).GetAwaiter().GetResult();
|
||||
deletedMessages.Add(i);
|
||||
}
|
||||
catch (ApiRequestException req) when (req.ErrorCode == 400)
|
||||
{
|
||||
deletedMessages.Add(i);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (AggregateException ex)
|
||||
{
|
||||
cts.Cancel();
|
||||
Device.DeleteMessage(i).GetAwaiter().GetResult();
|
||||
deletedMessages.Add(i);
|
||||
}
|
||||
catch (ApiRequestException req) when (req.ErrorCode == 400)
|
||||
{
|
||||
deletedMessages.Add(i);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (AggregateException ex)
|
||||
{
|
||||
cts.Cancel();
|
||||
|
||||
var retryAfterSeconds = ex.InnerExceptions
|
||||
.Where(e => e is ApiRequestException apiEx && apiEx.ErrorCode == 429)
|
||||
.Max(e => ((ApiRequestException)e).Parameters.RetryAfter) ?? 0;
|
||||
retryAfterTask = Task.Delay(retryAfterSeconds * 1000);
|
||||
}
|
||||
var retryAfterSeconds = ex.InnerExceptions
|
||||
.Where(e => e is ApiRequestException apiEx && apiEx.ErrorCode == 429)
|
||||
.Max(e => ((ApiRequestException)e).Parameters.RetryAfter) ?? 0;
|
||||
retryAfterTask = Task.Delay(retryAfterSeconds * 1000);
|
||||
}
|
||||
|
||||
//deletedMessages.AsParallel().ForAll(i => Device.OnMessageDeleted(new MessageDeletedEventArgs(i)));
|
||||
|
||||
oldMessages = oldMessages.Where(x => !deletedMessages.Contains(x));
|
||||
if (retryAfterTask != null)
|
||||
await retryAfterTask;
|
||||
//deletedMessages.AsParallel().ForAll(i => Device.OnMessageDeleted(new MessageDeletedEventArgs(i)));
|
||||
oldMessages = oldMessages.Where(x => !deletedMessages.Contains(x));
|
||||
if (retryAfterTask != null)
|
||||
{
|
||||
await retryAfterTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
OldMessages.Clear();
|
||||
}
|
||||
OldMessages.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,66 +1,62 @@
|
||||
using System.Diagnostics;
|
||||
using Telegram.Bot.Types.ReplyMarkups;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
namespace TelegramBotBase.Form;
|
||||
|
||||
[DebuggerDisplay("{Text}, {Value}")]
|
||||
/// <summary>
|
||||
/// Base class for button handling
|
||||
/// </summary>
|
||||
public class ButtonBase
|
||||
{
|
||||
[DebuggerDisplay("{Text}, {Value}")]
|
||||
/// <summary>
|
||||
/// Base class for button handling
|
||||
/// </summary>
|
||||
public class ButtonBase
|
||||
public ButtonBase()
|
||||
{
|
||||
public virtual string Text { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
|
||||
public string Url { get; set; }
|
||||
|
||||
public ButtonBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ButtonBase(string text, string value, string url = null)
|
||||
{
|
||||
this.Text = text;
|
||||
this.Value = value;
|
||||
this.Url = url;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns an inline Button
|
||||
/// </summary>
|
||||
/// <param name="form"></param>
|
||||
/// <returns></returns>
|
||||
public virtual InlineKeyboardButton ToInlineButton(ButtonForm form)
|
||||
{
|
||||
var id = (form.DependencyControl != null ? form.DependencyControl.ControlId + "_" : "");
|
||||
if (Url == null)
|
||||
{
|
||||
return InlineKeyboardButton.WithCallbackData(Text, id + Value);
|
||||
}
|
||||
|
||||
var ikb = new InlineKeyboardButton(Text)
|
||||
{
|
||||
//ikb.Text = this.Text;
|
||||
Url = Url
|
||||
};
|
||||
|
||||
return ikb;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a KeyBoardButton
|
||||
/// </summary>
|
||||
/// <param name="form"></param>
|
||||
/// <returns></returns>
|
||||
public virtual KeyboardButton ToKeyboardButton(ButtonForm form)
|
||||
{
|
||||
return new KeyboardButton(Text);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public ButtonBase(string text, string value, string url = null)
|
||||
{
|
||||
Text = text;
|
||||
Value = value;
|
||||
Url = url;
|
||||
}
|
||||
|
||||
public virtual string Text { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
|
||||
public string Url { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns an inline Button
|
||||
/// </summary>
|
||||
/// <param name="form"></param>
|
||||
/// <returns></returns>
|
||||
public virtual InlineKeyboardButton ToInlineButton(ButtonForm form)
|
||||
{
|
||||
var id = form.DependencyControl != null ? form.DependencyControl.ControlId + "_" : "";
|
||||
if (Url == null)
|
||||
{
|
||||
return InlineKeyboardButton.WithCallbackData(Text, id + Value);
|
||||
}
|
||||
|
||||
var ikb = new InlineKeyboardButton(Text)
|
||||
{
|
||||
//ikb.Text = this.Text;
|
||||
Url = Url
|
||||
};
|
||||
|
||||
return ikb;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a KeyBoardButton
|
||||
/// </summary>
|
||||
/// <param name="form"></param>
|
||||
/// <returns></returns>
|
||||
public virtual KeyboardButton ToKeyboardButton(ButtonForm form)
|
||||
{
|
||||
return new KeyboardButton(Text);
|
||||
}
|
||||
}
|
||||
+321
-305
@@ -5,321 +5,337 @@ using Telegram.Bot.Types.ReplyMarkups;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Controls.Hybrid;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
namespace TelegramBotBase.Form;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for an buttons array
|
||||
/// </summary>
|
||||
public class ButtonForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for an buttons array
|
||||
/// </summary>
|
||||
public class ButtonForm
|
||||
private readonly List<ButtonRow> _buttons = new();
|
||||
|
||||
public ButtonForm()
|
||||
{
|
||||
private List<ButtonRow> _buttons = new List<ButtonRow>();
|
||||
}
|
||||
|
||||
public ButtonForm(ControlBase control)
|
||||
{
|
||||
DependencyControl = control;
|
||||
}
|
||||
|
||||
|
||||
public IReplyMarkup Markup { get; set; }
|
||||
public IReplyMarkup Markup { get; set; }
|
||||
|
||||
public ControlBase DependencyControl { get; set; }
|
||||
public ControlBase DependencyControl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Contains the number of rows.
|
||||
/// </summary>
|
||||
public int Rows => _buttons.Count;
|
||||
/// <summary>
|
||||
/// Contains the number of rows.
|
||||
/// </summary>
|
||||
public int Rows => _buttons.Count;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the highest number of columns in an row.
|
||||
/// </summary>
|
||||
public int Cols
|
||||
/// <summary>
|
||||
/// Contains the highest number of columns in an row.
|
||||
/// </summary>
|
||||
public int Cols
|
||||
{
|
||||
get { return _buttons.Select(a => a.Count).OrderByDescending(a => a).FirstOrDefault(); }
|
||||
}
|
||||
|
||||
|
||||
public ButtonRow this[int row] => _buttons[row];
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
get
|
||||
if (_buttons.Count == 0)
|
||||
{
|
||||
return _buttons.Select(a => a.Count).OrderByDescending(a => a).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public ButtonRow this[int row] => _buttons[row];
|
||||
|
||||
public ButtonForm()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ButtonForm(ControlBase control)
|
||||
{
|
||||
DependencyControl = control;
|
||||
}
|
||||
|
||||
public void AddButtonRow(string text, string value, string url = null)
|
||||
{
|
||||
_buttons.Add(new List<ButtonBase> { new ButtonBase(text, value, url) });
|
||||
}
|
||||
|
||||
//public void AddButtonRow(ButtonRow row)
|
||||
//{
|
||||
// Buttons.Add(row.ToList());
|
||||
//}
|
||||
|
||||
public void AddButtonRow(ButtonRow row)
|
||||
{
|
||||
_buttons.Add(row);
|
||||
}
|
||||
|
||||
public void AddButtonRow(params ButtonBase[] row)
|
||||
{
|
||||
AddButtonRow(row.ToList());
|
||||
}
|
||||
|
||||
public void AddButtonRows(IEnumerable<ButtonRow> rows)
|
||||
{
|
||||
_buttons.AddRange(rows);
|
||||
}
|
||||
|
||||
public void InsertButtonRow(int index, IEnumerable<ButtonBase> row)
|
||||
{
|
||||
_buttons.Insert(index, row.ToList());
|
||||
}
|
||||
|
||||
public void InsertButtonRow(int index, ButtonRow row)
|
||||
{
|
||||
_buttons.Insert(index, row);
|
||||
}
|
||||
|
||||
//public void InsertButtonRow(int index, params ButtonBase[] row)
|
||||
//{
|
||||
// InsertButtonRow(index, row.ToList());
|
||||
//}
|
||||
|
||||
public static T[][] SplitTo<T>(IEnumerable<T> items, int itemsPerRow = 2)
|
||||
{
|
||||
var splitted = default(T[][]);
|
||||
|
||||
try
|
||||
{
|
||||
var t = items.Select((a, index) => new { a, index })
|
||||
.GroupBy(a => a.index / itemsPerRow)
|
||||
.Select(a => a.Select(b => b.a).ToArray()).ToArray();
|
||||
|
||||
splitted = t;
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return splitted;
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_buttons.Count == 0)
|
||||
return 0;
|
||||
|
||||
return _buttons.Select(a => a.ToArray()).ToList().Aggregate((a, b) => a.Union(b).ToArray()).Length;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add buttons splitted in the amount of columns (i.e. 2 per row...)
|
||||
/// </summary>
|
||||
/// <param name="buttons"></param>
|
||||
/// <param name="buttonsPerRow"></param>
|
||||
public void AddSplitted(IEnumerable<ButtonBase> buttons, int buttonsPerRow = 2)
|
||||
{
|
||||
var sp = SplitTo(buttons, buttonsPerRow);
|
||||
|
||||
foreach (var bl in sp)
|
||||
{
|
||||
AddButtonRow(bl);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a range of rows from the buttons.
|
||||
/// </summary>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
public List<ButtonRow> GetRange(int start, int count)
|
||||
{
|
||||
return _buttons.Skip(start).Take(count).ToList();
|
||||
}
|
||||
|
||||
|
||||
public List<ButtonBase> ToList()
|
||||
{
|
||||
return _buttons.DefaultIfEmpty(new List<ButtonBase>()).Select(a => a.ToList()).Aggregate((a, b) => a.Union(b).ToList());
|
||||
}
|
||||
|
||||
public InlineKeyboardButton[][] ToInlineButtonArray()
|
||||
{
|
||||
var ikb = _buttons.Select(a => a.ToArray().Select(b => b.ToInlineButton(this)).ToArray()).ToArray();
|
||||
|
||||
return ikb;
|
||||
}
|
||||
|
||||
public KeyboardButton[][] ToReplyButtonArray()
|
||||
{
|
||||
var ikb = _buttons.Select(a => a.ToArray().Select(b => b.ToKeyboardButton(this)).ToArray()).ToArray();
|
||||
|
||||
return ikb;
|
||||
}
|
||||
|
||||
public List<ButtonRow> ToArray()
|
||||
{
|
||||
return _buttons;
|
||||
}
|
||||
|
||||
public int FindRowByButton(ButtonBase button)
|
||||
{
|
||||
var row = _buttons.FirstOrDefault(a => a.ToArray().Count(b => b == button) > 0);
|
||||
if (row == null)
|
||||
return -1;
|
||||
|
||||
return _buttons.IndexOf(row);
|
||||
}
|
||||
|
||||
public Tuple<ButtonRow, int> FindRow(string text, bool useText = true)
|
||||
{
|
||||
var r = _buttons.FirstOrDefault(a => a.Matches(text, useText));
|
||||
if (r == null)
|
||||
return null;
|
||||
|
||||
var i = _buttons.IndexOf(r);
|
||||
return new Tuple<ButtonRow, int>(r, i);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the first Button with the given value.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public ButtonBase GetButtonByValue(string value)
|
||||
{
|
||||
return ToList().Where(a => a.Value == value).FirstOrDefault();
|
||||
}
|
||||
|
||||
public static implicit operator InlineKeyboardMarkup(ButtonForm form)
|
||||
{
|
||||
if (form == null)
|
||||
return null;
|
||||
|
||||
var ikm = new InlineKeyboardMarkup(form.ToInlineButtonArray());
|
||||
|
||||
return ikm;
|
||||
}
|
||||
|
||||
public static implicit operator ReplyKeyboardMarkup(ButtonForm form)
|
||||
{
|
||||
if (form == null)
|
||||
return null;
|
||||
|
||||
var ikm = new ReplyKeyboardMarkup(form.ToReplyButtonArray());
|
||||
|
||||
return ikm;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a copy of this form.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ButtonForm Duplicate()
|
||||
{
|
||||
var bf = new ButtonForm
|
||||
{
|
||||
Markup = Markup,
|
||||
DependencyControl = DependencyControl
|
||||
};
|
||||
|
||||
foreach (var b in _buttons)
|
||||
{
|
||||
var lst = new ButtonRow();
|
||||
foreach (var b2 in b)
|
||||
{
|
||||
lst.Add(b2);
|
||||
}
|
||||
bf._buttons.Add(lst);
|
||||
}
|
||||
|
||||
return bf;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a copy of this form and filters by the parameter.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ButtonForm FilterDuplicate(string filter, bool byRow = false)
|
||||
{
|
||||
var bf = new ButtonForm
|
||||
{
|
||||
Markup = Markup,
|
||||
DependencyControl = DependencyControl
|
||||
};
|
||||
|
||||
foreach (var b in _buttons)
|
||||
{
|
||||
var lst = new ButtonRow();
|
||||
foreach (var b2 in b)
|
||||
{
|
||||
if (b2.Text.IndexOf(filter, StringComparison.InvariantCultureIgnoreCase) == -1)
|
||||
continue;
|
||||
|
||||
//Copy full row, when at least one match has found.
|
||||
if (byRow)
|
||||
{
|
||||
lst = b;
|
||||
break;
|
||||
}
|
||||
|
||||
lst.Add(b2);
|
||||
}
|
||||
|
||||
if (lst.Count > 0)
|
||||
bf._buttons.Add(lst);
|
||||
}
|
||||
|
||||
return bf;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a copy of this form and filters by the parameter.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ButtonForm TagDuplicate(List<string> tags, bool byRow = false)
|
||||
{
|
||||
var bf = new ButtonForm
|
||||
{
|
||||
Markup = Markup,
|
||||
DependencyControl = DependencyControl
|
||||
};
|
||||
|
||||
foreach (var b in _buttons)
|
||||
{
|
||||
var lst = new ButtonRow();
|
||||
foreach (var b2 in b)
|
||||
{
|
||||
if (!(b2 is TagButtonBase tb))
|
||||
continue;
|
||||
|
||||
if (!tags.Contains(tb.Tag))
|
||||
continue;
|
||||
|
||||
//Copy full row, when at least one match has found.
|
||||
if (byRow)
|
||||
{
|
||||
lst = b;
|
||||
break;
|
||||
}
|
||||
|
||||
lst.Add(b2);
|
||||
}
|
||||
|
||||
if (lst.Count > 0)
|
||||
bf._buttons.Add(lst);
|
||||
}
|
||||
|
||||
return bf;
|
||||
return _buttons.Select(a => a.ToArray()).ToList().Aggregate((a, b) => a.Union(b).ToArray()).Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddButtonRow(string text, string value, string url = null)
|
||||
{
|
||||
_buttons.Add(new List<ButtonBase> { new(text, value, url) });
|
||||
}
|
||||
|
||||
//public void AddButtonRow(ButtonRow row)
|
||||
//{
|
||||
// Buttons.Add(row.ToList());
|
||||
//}
|
||||
|
||||
public void AddButtonRow(ButtonRow row)
|
||||
{
|
||||
_buttons.Add(row);
|
||||
}
|
||||
|
||||
public void AddButtonRow(params ButtonBase[] row)
|
||||
{
|
||||
AddButtonRow(row.ToList());
|
||||
}
|
||||
|
||||
public void AddButtonRows(IEnumerable<ButtonRow> rows)
|
||||
{
|
||||
_buttons.AddRange(rows);
|
||||
}
|
||||
|
||||
public void InsertButtonRow(int index, IEnumerable<ButtonBase> row)
|
||||
{
|
||||
_buttons.Insert(index, row.ToList());
|
||||
}
|
||||
|
||||
public void InsertButtonRow(int index, ButtonRow row)
|
||||
{
|
||||
_buttons.Insert(index, row);
|
||||
}
|
||||
|
||||
//public void InsertButtonRow(int index, params ButtonBase[] row)
|
||||
//{
|
||||
// InsertButtonRow(index, row.ToList());
|
||||
//}
|
||||
|
||||
public static T[][] SplitTo<T>(IEnumerable<T> items, int itemsPerRow = 2)
|
||||
{
|
||||
var splitted = default(T[][]);
|
||||
|
||||
try
|
||||
{
|
||||
var t = items.Select((a, index) => new { a, index })
|
||||
.GroupBy(a => a.index / itemsPerRow)
|
||||
.Select(a => a.Select(b => b.a).ToArray()).ToArray();
|
||||
|
||||
splitted = t;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
return splitted;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add buttons splitted in the amount of columns (i.e. 2 per row...)
|
||||
/// </summary>
|
||||
/// <param name="buttons"></param>
|
||||
/// <param name="buttonsPerRow"></param>
|
||||
public void AddSplitted(IEnumerable<ButtonBase> buttons, int buttonsPerRow = 2)
|
||||
{
|
||||
var sp = SplitTo(buttons, buttonsPerRow);
|
||||
|
||||
foreach (var bl in sp)
|
||||
{
|
||||
AddButtonRow(bl);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a range of rows from the buttons.
|
||||
/// </summary>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
public List<ButtonRow> GetRange(int start, int count)
|
||||
{
|
||||
return _buttons.Skip(start).Take(count).ToList();
|
||||
}
|
||||
|
||||
|
||||
public List<ButtonBase> ToList()
|
||||
{
|
||||
return _buttons.DefaultIfEmpty(new List<ButtonBase>()).Select(a => a.ToList())
|
||||
.Aggregate((a, b) => a.Union(b).ToList());
|
||||
}
|
||||
|
||||
public InlineKeyboardButton[][] ToInlineButtonArray()
|
||||
{
|
||||
var ikb = _buttons.Select(a => a.ToArray().Select(b => b.ToInlineButton(this)).ToArray()).ToArray();
|
||||
|
||||
return ikb;
|
||||
}
|
||||
|
||||
public KeyboardButton[][] ToReplyButtonArray()
|
||||
{
|
||||
var ikb = _buttons.Select(a => a.ToArray().Select(b => b.ToKeyboardButton(this)).ToArray()).ToArray();
|
||||
|
||||
return ikb;
|
||||
}
|
||||
|
||||
public List<ButtonRow> ToArray()
|
||||
{
|
||||
return _buttons;
|
||||
}
|
||||
|
||||
public int FindRowByButton(ButtonBase button)
|
||||
{
|
||||
var row = _buttons.FirstOrDefault(a => a.ToArray().Count(b => b == button) > 0);
|
||||
if (row == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _buttons.IndexOf(row);
|
||||
}
|
||||
|
||||
public Tuple<ButtonRow, int> FindRow(string text, bool useText = true)
|
||||
{
|
||||
var r = _buttons.FirstOrDefault(a => a.Matches(text, useText));
|
||||
if (r == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var i = _buttons.IndexOf(r);
|
||||
return new Tuple<ButtonRow, int>(r, i);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the first Button with the given value.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public ButtonBase GetButtonByValue(string value)
|
||||
{
|
||||
return ToList().Where(a => a.Value == value).FirstOrDefault();
|
||||
}
|
||||
|
||||
public static implicit operator InlineKeyboardMarkup(ButtonForm form)
|
||||
{
|
||||
if (form == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var ikm = new InlineKeyboardMarkup(form.ToInlineButtonArray());
|
||||
|
||||
return ikm;
|
||||
}
|
||||
|
||||
public static implicit operator ReplyKeyboardMarkup(ButtonForm form)
|
||||
{
|
||||
if (form == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var ikm = new ReplyKeyboardMarkup(form.ToReplyButtonArray());
|
||||
|
||||
return ikm;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a copy of this form.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ButtonForm Duplicate()
|
||||
{
|
||||
var bf = new ButtonForm
|
||||
{
|
||||
Markup = Markup,
|
||||
DependencyControl = DependencyControl
|
||||
};
|
||||
|
||||
foreach (var b in _buttons)
|
||||
{
|
||||
var lst = new ButtonRow();
|
||||
foreach (var b2 in b)
|
||||
{
|
||||
lst.Add(b2);
|
||||
}
|
||||
|
||||
bf._buttons.Add(lst);
|
||||
}
|
||||
|
||||
return bf;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a copy of this form and filters by the parameter.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ButtonForm FilterDuplicate(string filter, bool byRow = false)
|
||||
{
|
||||
var bf = new ButtonForm
|
||||
{
|
||||
Markup = Markup,
|
||||
DependencyControl = DependencyControl
|
||||
};
|
||||
|
||||
foreach (var b in _buttons)
|
||||
{
|
||||
var lst = new ButtonRow();
|
||||
foreach (var b2 in b)
|
||||
{
|
||||
if (b2.Text.IndexOf(filter, StringComparison.InvariantCultureIgnoreCase) == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//Copy full row, when at least one match has found.
|
||||
if (byRow)
|
||||
{
|
||||
lst = b;
|
||||
break;
|
||||
}
|
||||
|
||||
lst.Add(b2);
|
||||
}
|
||||
|
||||
if (lst.Count > 0)
|
||||
{
|
||||
bf._buttons.Add(lst);
|
||||
}
|
||||
}
|
||||
|
||||
return bf;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a copy of this form and filters by the parameter.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ButtonForm TagDuplicate(List<string> tags, bool byRow = false)
|
||||
{
|
||||
var bf = new ButtonForm
|
||||
{
|
||||
Markup = Markup,
|
||||
DependencyControl = DependencyControl
|
||||
};
|
||||
|
||||
foreach (var b in _buttons)
|
||||
{
|
||||
var lst = new ButtonRow();
|
||||
foreach (var b2 in b)
|
||||
{
|
||||
if (!(b2 is TagButtonBase tb))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!tags.Contains(tb.Tag))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//Copy full row, when at least one match has found.
|
||||
if (byRow)
|
||||
{
|
||||
lst = b;
|
||||
break;
|
||||
}
|
||||
|
||||
lst.Add(b2);
|
||||
}
|
||||
|
||||
if (lst.Count > 0)
|
||||
{
|
||||
bf._buttons.Add(lst);
|
||||
}
|
||||
}
|
||||
|
||||
return bf;
|
||||
}
|
||||
}
|
||||
@@ -1,76 +1,67 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
namespace TelegramBotBase.Form;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for serializing buttons and data
|
||||
/// </summary>
|
||||
public class CallbackData
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for serializing buttons and data
|
||||
/// </summary>
|
||||
public class CallbackData
|
||||
public CallbackData()
|
||||
{
|
||||
[JsonProperty("m")]
|
||||
public string Method { get; set; }
|
||||
|
||||
[JsonProperty("v")]
|
||||
public string Value { get; set; }
|
||||
|
||||
|
||||
public CallbackData()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public CallbackData(string method, string value)
|
||||
{
|
||||
Method = method;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public static string Create(string method, string value)
|
||||
{
|
||||
return new CallbackData(method, value).Serialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes data to json string
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string Serialize()
|
||||
{
|
||||
var s = "";
|
||||
try
|
||||
{
|
||||
|
||||
s = JsonConvert.SerializeObject(this);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes data from json string
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public static CallbackData Deserialize(string data)
|
||||
{
|
||||
CallbackData cd = null;
|
||||
try
|
||||
{
|
||||
cd = JsonConvert.DeserializeObject<CallbackData>(data);
|
||||
|
||||
return cd;
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public CallbackData(string method, string value)
|
||||
{
|
||||
Method = method;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
[JsonProperty("m")] public string Method { get; set; }
|
||||
|
||||
[JsonProperty("v")] public string Value { get; set; }
|
||||
|
||||
public static string Create(string method, string value)
|
||||
{
|
||||
return new CallbackData(method, value).Serialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes data to json string
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string Serialize()
|
||||
{
|
||||
var s = "";
|
||||
try
|
||||
{
|
||||
s = JsonConvert.SerializeObject(this);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes data from json string
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public static CallbackData Deserialize(string data)
|
||||
{
|
||||
CallbackData cd = null;
|
||||
try
|
||||
{
|
||||
cd = JsonConvert.DeserializeObject<CallbackData>(data);
|
||||
|
||||
return cd;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,115 +1,119 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Args;
|
||||
using TelegramBotBase.Attributes;
|
||||
using TelegramBotBase.Base;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
namespace TelegramBotBase.Form;
|
||||
|
||||
[IgnoreState]
|
||||
public class ConfirmDialog : ModalDialog
|
||||
{
|
||||
[IgnoreState]
|
||||
public class ConfirmDialog : ModalDialog
|
||||
public ConfirmDialog()
|
||||
{
|
||||
/// <summary>
|
||||
/// The message the users sees.
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// An additional optional value.
|
||||
/// </summary>
|
||||
public object Tag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Automatically close form on button click
|
||||
/// </summary>
|
||||
public bool AutoCloseOnClick { get; set; } = true;
|
||||
|
||||
public List<ButtonBase> Buttons { get; set; }
|
||||
|
||||
private static object EvButtonClicked { get; } = new object();
|
||||
|
||||
public ConfirmDialog()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ConfirmDialog(string message)
|
||||
{
|
||||
this.Message = message;
|
||||
Buttons = new List<ButtonBase>();
|
||||
}
|
||||
|
||||
public ConfirmDialog(string message, params ButtonBase[] buttons)
|
||||
{
|
||||
this.Message = message;
|
||||
this.Buttons = buttons.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds one Button
|
||||
/// </summary>
|
||||
/// <param name="button"></param>
|
||||
public void AddButton(ButtonBase button)
|
||||
{
|
||||
Buttons.Add(button);
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
if (message.Handled)
|
||||
return;
|
||||
|
||||
if (!message.IsFirstHandler)
|
||||
return;
|
||||
|
||||
var call = message.GetData<CallbackData>();
|
||||
if (call == null)
|
||||
return;
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
await message.ConfirmAction();
|
||||
|
||||
await message.DeleteMessage();
|
||||
|
||||
var button = Buttons.FirstOrDefault(a => a.Value == call.Value);
|
||||
|
||||
if (button == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OnButtonClicked(new ButtonClickedEventArgs(button) { Tag = Tag });
|
||||
|
||||
if (AutoCloseOnClick)
|
||||
await CloseForm();
|
||||
}
|
||||
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
var btn = new ButtonForm();
|
||||
|
||||
var buttons = Buttons.Select(a => new ButtonBase(a.Text, CallbackData.Create("action", a.Value))).ToList();
|
||||
btn.AddButtonRow(buttons);
|
||||
|
||||
await Device.Send(Message, btn);
|
||||
}
|
||||
|
||||
|
||||
public event EventHandler<ButtonClickedEventArgs> ButtonClicked
|
||||
{
|
||||
add => Events.AddHandler(EvButtonClicked, value);
|
||||
remove => Events.RemoveHandler(EvButtonClicked, value);
|
||||
}
|
||||
|
||||
public void OnButtonClicked(ButtonClickedEventArgs e)
|
||||
{
|
||||
(Events[EvButtonClicked] as EventHandler<ButtonClickedEventArgs>)?.Invoke(this, e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public ConfirmDialog(string message)
|
||||
{
|
||||
Message = message;
|
||||
Buttons = new List<ButtonBase>();
|
||||
}
|
||||
|
||||
public ConfirmDialog(string message, params ButtonBase[] buttons)
|
||||
{
|
||||
Message = message;
|
||||
Buttons = buttons.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The message the users sees.
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// An additional optional value.
|
||||
/// </summary>
|
||||
public object Tag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Automatically close form on button click
|
||||
/// </summary>
|
||||
public bool AutoCloseOnClick { get; set; } = true;
|
||||
|
||||
public List<ButtonBase> Buttons { get; set; }
|
||||
|
||||
private static object EvButtonClicked { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Adds one Button
|
||||
/// </summary>
|
||||
/// <param name="button"></param>
|
||||
public void AddButton(ButtonBase button)
|
||||
{
|
||||
Buttons.Add(button);
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
if (message.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!message.IsFirstHandler)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var call = message.GetData<CallbackData>();
|
||||
if (call == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
await message.ConfirmAction();
|
||||
|
||||
await message.DeleteMessage();
|
||||
|
||||
var button = Buttons.FirstOrDefault(a => a.Value == call.Value);
|
||||
|
||||
if (button == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OnButtonClicked(new ButtonClickedEventArgs(button) { Tag = Tag });
|
||||
|
||||
if (AutoCloseOnClick)
|
||||
{
|
||||
await CloseForm();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
var btn = new ButtonForm();
|
||||
|
||||
var buttons = Buttons.Select(a => new ButtonBase(a.Text, CallbackData.Create("action", a.Value))).ToList();
|
||||
btn.AddButtonRow(buttons);
|
||||
|
||||
await Device.Send(Message, btn);
|
||||
}
|
||||
|
||||
|
||||
public event EventHandler<ButtonClickedEventArgs> ButtonClicked
|
||||
{
|
||||
add => Events.AddHandler(EvButtonClicked, value);
|
||||
remove => Events.RemoveHandler(EvButtonClicked, value);
|
||||
}
|
||||
|
||||
public void OnButtonClicked(ButtonClickedEventArgs e)
|
||||
{
|
||||
(Events[EvButtonClicked] as EventHandler<ButtonClickedEventArgs>)?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,30 @@
|
||||
using System;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
namespace TelegramBotBase.Form;
|
||||
|
||||
public class DynamicButton : ButtonBase
|
||||
{
|
||||
public class DynamicButton : ButtonBase
|
||||
private readonly Func<string> _getText;
|
||||
|
||||
private string _mText = "";
|
||||
|
||||
public DynamicButton(string text, string value, string url = null)
|
||||
{
|
||||
public override string Text
|
||||
{
|
||||
get => _getText?.Invoke() ?? _mText;
|
||||
set => _mText = value;
|
||||
}
|
||||
|
||||
private string _mText = "";
|
||||
|
||||
private Func<string> _getText;
|
||||
|
||||
public DynamicButton(string text, string value, string url = null)
|
||||
{
|
||||
this.Text = text;
|
||||
this.Value = value;
|
||||
this.Url = url;
|
||||
}
|
||||
|
||||
public DynamicButton(Func<string> getText, string value, string url = null)
|
||||
{
|
||||
this._getText = getText;
|
||||
this.Value = value;
|
||||
this.Url = url;
|
||||
}
|
||||
|
||||
|
||||
Text = text;
|
||||
Value = value;
|
||||
Url = url;
|
||||
}
|
||||
}
|
||||
|
||||
public DynamicButton(Func<string> getText, string value, string url = null)
|
||||
{
|
||||
_getText = getText;
|
||||
Value = value;
|
||||
Url = url;
|
||||
}
|
||||
|
||||
public override string Text
|
||||
{
|
||||
get => _getText?.Invoke() ?? _mText;
|
||||
set => _mText = value;
|
||||
}
|
||||
}
|
||||
@@ -3,73 +3,73 @@ using Telegram.Bot.Types.Enums;
|
||||
using TelegramBotBase.Args;
|
||||
using TelegramBotBase.Base;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
namespace TelegramBotBase.Form;
|
||||
|
||||
public class GroupForm : FormBase
|
||||
{
|
||||
public class GroupForm : FormBase
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
public override async Task Load(MessageResult message)
|
||||
switch (message.MessageType)
|
||||
{
|
||||
switch (message.MessageType)
|
||||
{
|
||||
case MessageType.ChatMembersAdded:
|
||||
case MessageType.ChatMembersAdded:
|
||||
|
||||
await OnMemberChanges(new MemberChangeEventArgs(MessageType.ChatMembersAdded, message, message.Message.NewChatMembers));
|
||||
await OnMemberChanges(new MemberChangeEventArgs(MessageType.ChatMembersAdded, message,
|
||||
message.Message.NewChatMembers));
|
||||
|
||||
break;
|
||||
case MessageType.ChatMemberLeft:
|
||||
break;
|
||||
case MessageType.ChatMemberLeft:
|
||||
|
||||
await OnMemberChanges(new MemberChangeEventArgs(MessageType.ChatMemberLeft, message, message.Message.LeftChatMember));
|
||||
await OnMemberChanges(new MemberChangeEventArgs(MessageType.ChatMemberLeft, message,
|
||||
message.Message.LeftChatMember));
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case MessageType.ChatPhotoChanged:
|
||||
case MessageType.ChatPhotoDeleted:
|
||||
case MessageType.ChatTitleChanged:
|
||||
case MessageType.MigratedFromGroup:
|
||||
case MessageType.MigratedToSupergroup:
|
||||
case MessageType.MessagePinned:
|
||||
case MessageType.GroupCreated:
|
||||
case MessageType.SupergroupCreated:
|
||||
case MessageType.ChannelCreated:
|
||||
case MessageType.ChatPhotoChanged:
|
||||
case MessageType.ChatPhotoDeleted:
|
||||
case MessageType.ChatTitleChanged:
|
||||
case MessageType.MigratedFromGroup:
|
||||
case MessageType.MigratedToSupergroup:
|
||||
case MessageType.MessagePinned:
|
||||
case MessageType.GroupCreated:
|
||||
case MessageType.SupergroupCreated:
|
||||
case MessageType.ChannelCreated:
|
||||
|
||||
await OnGroupChanged(new GroupChangedEventArgs(message.MessageType, message));
|
||||
await OnGroupChanged(new GroupChangedEventArgs(message.MessageType, message));
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
default:
|
||||
|
||||
await OnMessage(message);
|
||||
await OnMessage(message);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override async Task Edited(MessageResult message)
|
||||
{
|
||||
await OnMessageEdit(message);
|
||||
}
|
||||
|
||||
public virtual Task OnMemberChanges(MemberChangeEventArgs e)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
public virtual Task OnGroupChanged(GroupChangedEventArgs e)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
public virtual Task OnMessage(MessageResult e)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public virtual Task OnMessageEdit(MessageResult e)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task Edited(MessageResult message)
|
||||
{
|
||||
await OnMessageEdit(message);
|
||||
}
|
||||
|
||||
public virtual Task OnMemberChanges(MemberChangeEventArgs e)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
public virtual Task OnGroupChanged(GroupChangedEventArgs e)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
public virtual Task OnMessage(MessageResult e)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public virtual Task OnMessageEdit(MessageResult e)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,25 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
namespace TelegramBotBase.Form;
|
||||
|
||||
public class ModalDialog : FormBase
|
||||
{
|
||||
public class ModalDialog : FormBase
|
||||
/// <summary>
|
||||
/// Contains the parent from where the modal dialog has been opened.
|
||||
/// </summary>
|
||||
public FormBase ParentForm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This is a modal only function and does everything to close this form.
|
||||
/// </summary>
|
||||
public async Task CloseForm()
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains the parent from where the modal dialog has been opened.
|
||||
/// </summary>
|
||||
public FormBase ParentForm { get; set; }
|
||||
await CloseControls();
|
||||
|
||||
/// <summary>
|
||||
/// This is a modal only function and does everything to close this form.
|
||||
/// </summary>
|
||||
public async Task CloseForm()
|
||||
{
|
||||
await CloseControls();
|
||||
|
||||
await OnClosed(EventArgs.Empty);
|
||||
await OnClosed(EventArgs.Empty);
|
||||
|
||||
|
||||
await ParentForm?.ReturnFromModal(this);
|
||||
}
|
||||
await ParentForm?.ReturnFromModal(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,348 +10,356 @@ using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Interfaces;
|
||||
using TelegramBotBase.Tools;
|
||||
|
||||
namespace TelegramBotBase.Form.Navigation
|
||||
namespace TelegramBotBase.Form.Navigation;
|
||||
|
||||
[DebuggerDisplay("{Index+1} Forms")]
|
||||
public class NavigationController : FormBase, IStateForm
|
||||
{
|
||||
[DebuggerDisplay("{Index+1} Forms")]
|
||||
public class NavigationController : FormBase, IStateForm
|
||||
public NavigationController()
|
||||
{
|
||||
History = new List<FormBase>();
|
||||
Index = -1;
|
||||
ForceCleanupOnLastPop = true;
|
||||
|
||||
[SaveState]
|
||||
private List<FormBase> History { get; set; }
|
||||
Init += NavigationController_Init;
|
||||
Opened += NavigationController_Opened;
|
||||
Closed += NavigationController_Closed;
|
||||
}
|
||||
|
||||
[SaveState]
|
||||
public int Index { get; set; }
|
||||
public NavigationController(FormBase startForm, params FormBase[] forms) : this()
|
||||
{
|
||||
Client = startForm.Client;
|
||||
Device = startForm.Device;
|
||||
startForm.NavigationController = this;
|
||||
|
||||
/// <summary>
|
||||
/// Will replace the controller when poping a form to the root form.
|
||||
/// </summary>
|
||||
[SaveState]
|
||||
public bool ForceCleanupOnLastPop { get; set; }
|
||||
History.Add(startForm);
|
||||
Index = 0;
|
||||
|
||||
public NavigationController()
|
||||
if (forms.Length > 0)
|
||||
{
|
||||
History = new List<FormBase>();
|
||||
Index = -1;
|
||||
ForceCleanupOnLastPop = true;
|
||||
|
||||
Init += NavigationController_Init;
|
||||
Opened += NavigationController_Opened;
|
||||
Closed += NavigationController_Closed;
|
||||
History.AddRange(forms);
|
||||
Index = History.Count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
public NavigationController(FormBase startForm, params FormBase[] forms) : this()
|
||||
{
|
||||
Client = startForm.Client;
|
||||
Device = startForm.Device;
|
||||
startForm.NavigationController = this;
|
||||
[SaveState] private List<FormBase> History { get; }
|
||||
|
||||
History.Add(startForm);
|
||||
Index = 0;
|
||||
[SaveState] public int Index { get; set; }
|
||||
|
||||
if (forms.Length > 0)
|
||||
{
|
||||
History.AddRange(forms);
|
||||
Index = History.Count - 1;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Will replace the controller when poping a form to the root form.
|
||||
/// </summary>
|
||||
[SaveState]
|
||||
public bool ForceCleanupOnLastPop { get; set; }
|
||||
|
||||
private async Task NavigationController_Init(object sender, InitEventArgs e)
|
||||
{
|
||||
if (CurrentForm == null)
|
||||
return;
|
||||
|
||||
await CurrentForm.OnInit(e);
|
||||
}
|
||||
|
||||
private async Task NavigationController_Opened(object sender, EventArgs e)
|
||||
{
|
||||
if (CurrentForm == null)
|
||||
return;
|
||||
|
||||
await CurrentForm.OnOpened(e);
|
||||
}
|
||||
|
||||
private async Task NavigationController_Closed(object sender, EventArgs e)
|
||||
{
|
||||
if (CurrentForm == null)
|
||||
return;
|
||||
|
||||
await CurrentForm.OnClosed(e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Remove the current active form on the stack.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual async Task PopAsync()
|
||||
/// <summary>
|
||||
/// Returns the current form from the stack.
|
||||
/// </summary>
|
||||
public FormBase CurrentForm
|
||||
{
|
||||
get
|
||||
{
|
||||
if (History.Count == 0)
|
||||
return;
|
||||
|
||||
var form = History[Index];
|
||||
|
||||
form.NavigationController = null;
|
||||
History.Remove(form);
|
||||
Index--;
|
||||
|
||||
Device.FormSwitched = true;
|
||||
|
||||
await form.OnClosed(EventArgs.Empty);
|
||||
|
||||
//Leave NavigationController and move to the last one
|
||||
if (ForceCleanupOnLastPop && History.Count == 1)
|
||||
{
|
||||
var lastForm = History[0];
|
||||
lastForm.NavigationController = null;
|
||||
await NavigateTo(lastForm);
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (History.Count > 0)
|
||||
{
|
||||
form = History[Index];
|
||||
await form.OnOpened(EventArgs.Empty);
|
||||
}
|
||||
return History[Index];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void LoadState(LoadStateEventArgs e)
|
||||
{
|
||||
if (e.Get("$controller.history.count") == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pop's through all forms back to the root form.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual async Task PopToRootAsync()
|
||||
{
|
||||
while (Index > 0)
|
||||
{
|
||||
await PopAsync();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pushing the given form to the stack and renders it.
|
||||
/// </summary>
|
||||
/// <param name="form"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task PushAsync(FormBase form, params object[] args)
|
||||
var historyCount = e.GetInt("$controller.history.count");
|
||||
|
||||
for (var i = 0; i < historyCount; i++)
|
||||
{
|
||||
form.Client = Client;
|
||||
var c = e.GetObject($"$controller.history[{i}]") as Dictionary<string, object>;
|
||||
|
||||
|
||||
var qname = e.Get($"$controller.history[{i}].type");
|
||||
|
||||
if (qname == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var t = Type.GetType(qname);
|
||||
if (t == null || !t.IsSubclassOf(typeof(FormBase)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//No default constructor, fallback
|
||||
if (t.GetConstructor(new Type[] { })?.Invoke(new object[] { }) is not FormBase form)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var properties = c.Where(a => a.Key.StartsWith("$"));
|
||||
|
||||
var fields = form.GetType()
|
||||
.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
||||
.Where(a => a.GetCustomAttributes(typeof(SaveState), true).Length != 0).ToList();
|
||||
|
||||
foreach (var p in properties)
|
||||
{
|
||||
var f = fields.FirstOrDefault(a => a.Name == p.Key.Substring(1));
|
||||
if (f == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (f.PropertyType.IsEnum)
|
||||
{
|
||||
var ent = Enum.Parse(f.PropertyType, p.Value.ToString());
|
||||
|
||||
f.SetValue(form, ent);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
f.SetValue(form, p.Value);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
Conversion.CustomConversionChecks(form, p, f);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
form.Device = Device;
|
||||
form.Client = Client;
|
||||
form.NavigationController = this;
|
||||
|
||||
form.OnInit(new InitEventArgs());
|
||||
|
||||
History.Add(form);
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
|
||||
Device.FormSwitched = true;
|
||||
public void SaveState(SaveStateEventArgs e)
|
||||
{
|
||||
e.Set("$controller.history.count", History.Count.ToString());
|
||||
|
||||
if (Index < 2)
|
||||
return;
|
||||
var i = 0;
|
||||
foreach (var form in History)
|
||||
{
|
||||
var fields = form.GetType()
|
||||
.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
||||
.Where(a => a.GetCustomAttributes(typeof(SaveState), true).Length != 0).ToList();
|
||||
|
||||
await form.OnInit(new InitEventArgs(args));
|
||||
var dt = new Dictionary<string, object>();
|
||||
foreach (var f in fields)
|
||||
{
|
||||
var val = f.GetValue(form);
|
||||
|
||||
dt.Add("$" + f.Name, val);
|
||||
}
|
||||
|
||||
e.Set($"$controller.history[{i}].type", form.GetType().AssemblyQualifiedName);
|
||||
|
||||
e.SetObject($"$controller.history[{i}]", dt);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task NavigationController_Init(object sender, InitEventArgs e)
|
||||
{
|
||||
if (CurrentForm == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await CurrentForm.OnInit(e);
|
||||
}
|
||||
|
||||
private async Task NavigationController_Opened(object sender, EventArgs e)
|
||||
{
|
||||
if (CurrentForm == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await CurrentForm.OnOpened(e);
|
||||
}
|
||||
|
||||
private async Task NavigationController_Closed(object sender, EventArgs e)
|
||||
{
|
||||
if (CurrentForm == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await CurrentForm.OnClosed(e);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Remove the current active form on the stack.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual async Task PopAsync()
|
||||
{
|
||||
if (History.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var form = History[Index];
|
||||
|
||||
form.NavigationController = null;
|
||||
History.Remove(form);
|
||||
Index--;
|
||||
|
||||
Device.FormSwitched = true;
|
||||
|
||||
await form.OnClosed(EventArgs.Empty);
|
||||
|
||||
//Leave NavigationController and move to the last one
|
||||
if (ForceCleanupOnLastPop && History.Count == 1)
|
||||
{
|
||||
var lastForm = History[0];
|
||||
lastForm.NavigationController = null;
|
||||
await NavigateTo(lastForm);
|
||||
return;
|
||||
}
|
||||
|
||||
if (History.Count > 0)
|
||||
{
|
||||
form = History[Index];
|
||||
await form.OnOpened(EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pops the current form and pushes a new one.
|
||||
/// Will help to remove forms so you can not navigate back to them.
|
||||
/// </summary>
|
||||
/// <param name="form"></param>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task PushAndReplaceAsync(FormBase form, params object[] args)
|
||||
/// <summary>
|
||||
/// Pop's through all forms back to the root form.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual async Task PopToRootAsync()
|
||||
{
|
||||
while (Index > 0)
|
||||
{
|
||||
await PopAsync();
|
||||
|
||||
await PushAsync(form, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current form from the stack.
|
||||
/// </summary>
|
||||
public FormBase CurrentForm
|
||||
{
|
||||
get
|
||||
{
|
||||
if (History.Count == 0)
|
||||
return null;
|
||||
|
||||
return History[Index];
|
||||
}
|
||||
}
|
||||
|
||||
public List<FormBase> GetAllForms()
|
||||
{
|
||||
return History.ToList();
|
||||
}
|
||||
|
||||
|
||||
public void LoadState(LoadStateEventArgs e)
|
||||
{
|
||||
if (e.Get("$controller.history.count") == null)
|
||||
return;
|
||||
|
||||
|
||||
var historyCount = e.GetInt("$controller.history.count");
|
||||
|
||||
for (var i = 0; i < historyCount; i++)
|
||||
{
|
||||
|
||||
var c = e.GetObject($"$controller.history[{i}]") as Dictionary<string, object>;
|
||||
|
||||
|
||||
|
||||
var qname = e.Get($"$controller.history[{i}].type");
|
||||
|
||||
if (qname == null)
|
||||
continue;
|
||||
|
||||
var t = Type.GetType(qname);
|
||||
if (t == null || !t.IsSubclassOf(typeof(FormBase)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//No default constructor, fallback
|
||||
if (t.GetConstructor(new Type[] { })?.Invoke(new object[] { }) is not FormBase form)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var properties = c.Where(a => a.Key.StartsWith("$"));
|
||||
|
||||
var fields = form.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(a => a.GetCustomAttributes(typeof(SaveState), true).Length != 0).ToList();
|
||||
|
||||
foreach (var p in properties)
|
||||
{
|
||||
var f = fields.FirstOrDefault(a => a.Name == p.Key.Substring(1));
|
||||
if (f == null)
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
if (f.PropertyType.IsEnum)
|
||||
{
|
||||
var ent = Enum.Parse(f.PropertyType, p.Value.ToString());
|
||||
|
||||
f.SetValue(form, ent);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
f.SetValue(form, p.Value);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
|
||||
Conversion.CustomConversionChecks(form, p, f);
|
||||
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
form.Device = Device;
|
||||
form.Client = Client;
|
||||
form.NavigationController = this;
|
||||
|
||||
form.OnInit(new InitEventArgs());
|
||||
|
||||
History.Add(form);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void SaveState(SaveStateEventArgs e)
|
||||
{
|
||||
e.Set("$controller.history.count", History.Count.ToString());
|
||||
|
||||
var i = 0;
|
||||
foreach (var form in History)
|
||||
{
|
||||
var fields = form.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(a => a.GetCustomAttributes(typeof(SaveState), true).Length != 0).ToList();
|
||||
|
||||
var dt = new Dictionary<string, object>();
|
||||
foreach (var f in fields)
|
||||
{
|
||||
var val = f.GetValue(form);
|
||||
|
||||
dt.Add("$" + f.Name, val);
|
||||
}
|
||||
|
||||
e.Set($"$controller.history[{i}].type", form.GetType().AssemblyQualifiedName);
|
||||
|
||||
e.SetObject($"$controller.history[{i}]", dt);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region "Methods passthrough"
|
||||
|
||||
public override async Task NavigateTo(FormBase newForm, params object[] args)
|
||||
{
|
||||
await CurrentForm.NavigateTo(newForm, args);
|
||||
}
|
||||
|
||||
public override async Task LoadControls(MessageResult message)
|
||||
{
|
||||
await CurrentForm.LoadControls(message);
|
||||
}
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
await CurrentForm.Load(message);
|
||||
}
|
||||
|
||||
public override async Task ActionControls(MessageResult message)
|
||||
{
|
||||
await CurrentForm.ActionControls(message);
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
await CurrentForm.Action(message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override async Task Edited(MessageResult message)
|
||||
{
|
||||
await CurrentForm.Edited(message);
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
await CurrentForm.Render(message);
|
||||
}
|
||||
|
||||
public override async Task RenderControls(MessageResult message)
|
||||
{
|
||||
await CurrentForm.RenderControls(message);
|
||||
}
|
||||
|
||||
public override async Task PreLoad(MessageResult message)
|
||||
{
|
||||
await CurrentForm.PreLoad(message);
|
||||
}
|
||||
|
||||
public override async Task ReturnFromModal(ModalDialog modal)
|
||||
{
|
||||
await CurrentForm.ReturnFromModal(modal);
|
||||
}
|
||||
|
||||
public override async Task SentData(DataResult message)
|
||||
{
|
||||
await CurrentForm.SentData(message);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pushing the given form to the stack and renders it.
|
||||
/// </summary>
|
||||
/// <param name="form"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task PushAsync(FormBase form, params object[] args)
|
||||
{
|
||||
form.Client = Client;
|
||||
form.Device = Device;
|
||||
form.NavigationController = this;
|
||||
|
||||
History.Add(form);
|
||||
Index++;
|
||||
|
||||
Device.FormSwitched = true;
|
||||
|
||||
if (Index < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await form.OnInit(new InitEventArgs(args));
|
||||
|
||||
await form.OnOpened(EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pops the current form and pushes a new one.
|
||||
/// Will help to remove forms so you can not navigate back to them.
|
||||
/// </summary>
|
||||
/// <param name="form"></param>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task PushAndReplaceAsync(FormBase form, params object[] args)
|
||||
{
|
||||
await PopAsync();
|
||||
|
||||
await PushAsync(form, args);
|
||||
}
|
||||
|
||||
public List<FormBase> GetAllForms()
|
||||
{
|
||||
return History.ToList();
|
||||
}
|
||||
|
||||
|
||||
#region "Methods passthrough"
|
||||
|
||||
public override async Task NavigateTo(FormBase newForm, params object[] args)
|
||||
{
|
||||
await CurrentForm.NavigateTo(newForm, args);
|
||||
}
|
||||
|
||||
public override async Task LoadControls(MessageResult message)
|
||||
{
|
||||
await CurrentForm.LoadControls(message);
|
||||
}
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
await CurrentForm.Load(message);
|
||||
}
|
||||
|
||||
public override async Task ActionControls(MessageResult message)
|
||||
{
|
||||
await CurrentForm.ActionControls(message);
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
await CurrentForm.Action(message);
|
||||
}
|
||||
|
||||
|
||||
public override async Task Edited(MessageResult message)
|
||||
{
|
||||
await CurrentForm.Edited(message);
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
await CurrentForm.Render(message);
|
||||
}
|
||||
|
||||
public override async Task RenderControls(MessageResult message)
|
||||
{
|
||||
await CurrentForm.RenderControls(message);
|
||||
}
|
||||
|
||||
public override async Task PreLoad(MessageResult message)
|
||||
{
|
||||
await CurrentForm.PreLoad(message);
|
||||
}
|
||||
|
||||
public override async Task ReturnFromModal(ModalDialog modal)
|
||||
{
|
||||
await CurrentForm.ReturnFromModal(modal);
|
||||
}
|
||||
|
||||
public override async Task SentData(DataResult message)
|
||||
{
|
||||
await CurrentForm.SentData(message);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types;
|
||||
using Telegram.Bot.Types.ReplyMarkups;
|
||||
@@ -8,108 +7,106 @@ using TelegramBotBase.Attributes;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Localizations;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
namespace TelegramBotBase.Form;
|
||||
|
||||
[IgnoreState]
|
||||
public class PromptDialog : ModalDialog
|
||||
{
|
||||
[IgnoreState]
|
||||
public class PromptDialog : ModalDialog
|
||||
public PromptDialog()
|
||||
{
|
||||
/// <summary>
|
||||
/// The message the users sees.
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The returned text value by the user.
|
||||
/// </summary>
|
||||
public string Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// An additional optional value.
|
||||
/// </summary>
|
||||
public object Tag { get; set; }
|
||||
|
||||
private static object EvCompleted { get; } = new object();
|
||||
|
||||
public bool ShowBackButton { get; set; } = false;
|
||||
|
||||
public string BackLabel { get; set; } = Default.Language["PromptDialog_Back"];
|
||||
|
||||
/// <summary>
|
||||
/// Contains the RAW received message.
|
||||
/// </summary>
|
||||
public Message ReceivedMessage { get; set; }
|
||||
|
||||
public PromptDialog()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public PromptDialog(string message)
|
||||
{
|
||||
this.Message = message;
|
||||
}
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
if (message.Handled)
|
||||
return;
|
||||
|
||||
if (!message.IsFirstHandler)
|
||||
return;
|
||||
|
||||
if (ShowBackButton && message.MessageText == BackLabel)
|
||||
{
|
||||
await CloseForm();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (Value == null)
|
||||
{
|
||||
Value = message.MessageText;
|
||||
|
||||
ReceivedMessage = message.Message;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
|
||||
if (Value == null)
|
||||
{
|
||||
if (ShowBackButton)
|
||||
{
|
||||
var bf = new ButtonForm();
|
||||
bf.AddButtonRow(new ButtonBase(BackLabel, "back"));
|
||||
await Device.Send(Message, (ReplyMarkupBase)bf);
|
||||
return;
|
||||
}
|
||||
|
||||
await Device.Send(Message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
OnCompleted(new PromptDialogCompletedEventArgs { Tag = Tag, Value = Value });
|
||||
|
||||
await CloseForm();
|
||||
}
|
||||
|
||||
|
||||
public event EventHandler<PromptDialogCompletedEventArgs> Completed
|
||||
{
|
||||
add => Events.AddHandler(EvCompleted, value);
|
||||
remove => Events.RemoveHandler(EvCompleted, value);
|
||||
}
|
||||
|
||||
public void OnCompleted(PromptDialogCompletedEventArgs e)
|
||||
{
|
||||
(Events[EvCompleted] as EventHandler<PromptDialogCompletedEventArgs>)?.Invoke(this, e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public PromptDialog(string message)
|
||||
{
|
||||
Message = message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The message the users sees.
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The returned text value by the user.
|
||||
/// </summary>
|
||||
public string Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// An additional optional value.
|
||||
/// </summary>
|
||||
public object Tag { get; set; }
|
||||
|
||||
private static object EvCompleted { get; } = new();
|
||||
|
||||
public bool ShowBackButton { get; set; } = false;
|
||||
|
||||
public string BackLabel { get; set; } = Default.Language["PromptDialog_Back"];
|
||||
|
||||
/// <summary>
|
||||
/// Contains the RAW received message.
|
||||
/// </summary>
|
||||
public Message ReceivedMessage { get; set; }
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
if (message.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!message.IsFirstHandler)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ShowBackButton && message.MessageText == BackLabel)
|
||||
{
|
||||
await CloseForm();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (Value == null)
|
||||
{
|
||||
Value = message.MessageText;
|
||||
|
||||
ReceivedMessage = message.Message;
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
if (Value == null)
|
||||
{
|
||||
if (ShowBackButton)
|
||||
{
|
||||
var bf = new ButtonForm();
|
||||
bf.AddButtonRow(new ButtonBase(BackLabel, "back"));
|
||||
await Device.Send(Message, (ReplyMarkupBase)bf);
|
||||
return;
|
||||
}
|
||||
|
||||
await Device.Send(Message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
OnCompleted(new PromptDialogCompletedEventArgs { Tag = Tag, Value = Value });
|
||||
|
||||
await CloseForm();
|
||||
}
|
||||
|
||||
|
||||
public event EventHandler<PromptDialogCompletedEventArgs> Completed
|
||||
{
|
||||
add => Events.AddHandler(EvCompleted, value);
|
||||
remove => Events.RemoveHandler(EvCompleted, value);
|
||||
}
|
||||
|
||||
public void OnCompleted(PromptDialogCompletedEventArgs e)
|
||||
{
|
||||
(Events[EvCompleted] as EventHandler<PromptDialogCompletedEventArgs>)?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
@@ -2,95 +2,92 @@
|
||||
using Telegram.Bot.Types.Enums;
|
||||
using TelegramBotBase.Base;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
namespace TelegramBotBase.Form;
|
||||
|
||||
/// <summary>
|
||||
/// This is used to split incomming requests depending on the chat type.
|
||||
/// </summary>
|
||||
public class SplitterForm : FormBase
|
||||
{
|
||||
/// <summary>
|
||||
/// This is used to split incomming requests depending on the chat type.
|
||||
/// </summary>
|
||||
public class SplitterForm : FormBase
|
||||
private static object __evOpenSupergroup = new();
|
||||
private static object __evOpenGroup = new();
|
||||
private static object __evOpenChannel = new();
|
||||
private static object __evOpen = new();
|
||||
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
|
||||
private static object __evOpenSupergroup = new object();
|
||||
private static object __evOpenGroup = new object();
|
||||
private static object __evOpenChannel = new object();
|
||||
private static object __evOpen = new object();
|
||||
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
if (message.Message.Chat.Type == ChatType.Channel)
|
||||
{
|
||||
if (await OpenChannel(message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (message.Message.Chat.Type == ChatType.Channel)
|
||||
if (message.Message.Chat.Type == ChatType.Supergroup)
|
||||
{
|
||||
if (await OpenSupergroup(message))
|
||||
{
|
||||
if (await OpenChannel(message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (message.Message.Chat.Type == ChatType.Supergroup)
|
||||
{
|
||||
if (await OpenSupergroup(message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (await OpenGroup(message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (message.Message.Chat.Type == ChatType.Group)
|
||||
{
|
||||
if (await OpenGroup(message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
await Open(message);
|
||||
if (await OpenGroup(message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public virtual Task<bool> OpenSupergroup(MessageResult e)
|
||||
if (message.Message.Chat.Type == ChatType.Group)
|
||||
{
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
public virtual Task<bool> OpenChannel(MessageResult e)
|
||||
{
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
public virtual Task<bool> Open(MessageResult e)
|
||||
{
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
public virtual Task<bool> OpenGroup(MessageResult e)
|
||||
{
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public override Task Action(MessageResult message)
|
||||
{
|
||||
return base.Action(message);
|
||||
}
|
||||
|
||||
public override Task PreLoad(MessageResult message)
|
||||
{
|
||||
return base.PreLoad(message);
|
||||
}
|
||||
|
||||
public override Task Render(MessageResult message)
|
||||
{
|
||||
return base.Render(message);
|
||||
}
|
||||
|
||||
public override Task SentData(DataResult message)
|
||||
{
|
||||
return base.SentData(message);
|
||||
if (await OpenGroup(message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await Open(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public virtual Task<bool> OpenSupergroup(MessageResult e)
|
||||
{
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
public virtual Task<bool> OpenChannel(MessageResult e)
|
||||
{
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
public virtual Task<bool> Open(MessageResult e)
|
||||
{
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
public virtual Task<bool> OpenGroup(MessageResult e)
|
||||
{
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
|
||||
public override Task Action(MessageResult message)
|
||||
{
|
||||
return base.Action(message);
|
||||
}
|
||||
|
||||
public override Task PreLoad(MessageResult message)
|
||||
{
|
||||
return base.PreLoad(message);
|
||||
}
|
||||
|
||||
public override Task Render(MessageResult message)
|
||||
{
|
||||
return base.Render(message);
|
||||
}
|
||||
|
||||
public override Task SentData(DataResult message)
|
||||
{
|
||||
return base.SentData(message);
|
||||
}
|
||||
}
|
||||
@@ -1,50 +1,46 @@
|
||||
using Telegram.Bot.Types.ReplyMarkups;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
namespace TelegramBotBase.Form;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for button handling
|
||||
/// </summary>
|
||||
public class TagButtonBase : ButtonBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for button handling
|
||||
/// </summary>
|
||||
public class TagButtonBase : ButtonBase
|
||||
public TagButtonBase()
|
||||
{
|
||||
public string Tag { get; set; }
|
||||
|
||||
public TagButtonBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public TagButtonBase(string text, string value, string tag)
|
||||
{
|
||||
this.Text = text;
|
||||
this.Value = value;
|
||||
this.Tag = tag;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns an inline Button
|
||||
/// </summary>
|
||||
/// <param name="form"></param>
|
||||
/// <returns></returns>
|
||||
public override InlineKeyboardButton ToInlineButton(ButtonForm form)
|
||||
{
|
||||
var id = (form.DependencyControl != null ? form.DependencyControl.ControlId + "_" : "");
|
||||
|
||||
return InlineKeyboardButton.WithCallbackData(Text, id + Value);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a KeyBoardButton
|
||||
/// </summary>
|
||||
/// <param name="form"></param>
|
||||
/// <returns></returns>
|
||||
public override KeyboardButton ToKeyboardButton(ButtonForm form)
|
||||
{
|
||||
return new KeyboardButton(Text);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public TagButtonBase(string text, string value, string tag)
|
||||
{
|
||||
Text = text;
|
||||
Value = value;
|
||||
Tag = tag;
|
||||
}
|
||||
|
||||
public string Tag { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns an inline Button
|
||||
/// </summary>
|
||||
/// <param name="form"></param>
|
||||
/// <returns></returns>
|
||||
public override InlineKeyboardButton ToInlineButton(ButtonForm form)
|
||||
{
|
||||
var id = form.DependencyControl != null ? form.DependencyControl.ControlId + "_" : "";
|
||||
|
||||
return InlineKeyboardButton.WithCallbackData(Text, id + Value);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a KeyBoardButton
|
||||
/// </summary>
|
||||
/// <param name="form"></param>
|
||||
/// <returns></returns>
|
||||
public override KeyboardButton ToKeyboardButton(ButtonForm form)
|
||||
{
|
||||
return new KeyboardButton(Text);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user