New Control: MultiView

- adding basic paging options
- adding GetOrigin method to find control or form who has sent a message
- adding Test for MultiView
This commit is contained in:
FlorianDahn 2021-02-20 01:51:01 +01:00
parent dc8cb81284
commit fc44b7d38c
8 changed files with 388 additions and 42 deletions

View File

@ -19,9 +19,16 @@ namespace TelegramBotBase.Args
public Message Message { get; set; }
public MessageSentEventArgs(Message message)
/// <summary>
/// Contains the element, which has called the method.
/// </summary>
public Type Origin { get; set; }
public MessageSentEventArgs(Message message, Type Origin)
{
this.Message = message;
this.Origin = Origin;
}

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace TelegramBotBase.Args
{
public class RenderViewEventArgs : EventArgs
{
public int CurrentView { get; set; }
public RenderViewEventArgs(int ViewIndex)
{
CurrentView = ViewIndex;
}
}
}

View File

@ -0,0 +1,133 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TelegramBotBase.Args;
using TelegramBotBase.Base;
using static TelegramBotBase.Base.Async;
namespace TelegramBotBase.Controls.Hybrid
{
/// <summary>
/// This Control is for having a basic form content switching control.
/// </summary>
public abstract class MultiView : Base.ControlBase
{
/// <summary>
/// Index of the current View.
/// </summary>
public int SelectedViewIndex
{
get
{
return m_iSelectedViewIndex;
}
set
{
m_iSelectedViewIndex = value;
//Already rendered? Re-Render
if (_Rendered)
ForceRender().Wait();
}
}
private int m_iSelectedViewIndex = 0;
/// <summary>
/// Hold if the View has been rendered already.
/// </summary>
private bool _Rendered = false;
private List<int> Messages { get; set; }
public MultiView()
{
Messages = new List<int>();
}
private void Device_MessageSent(object sender, MessageSentEventArgs e)
{
if (e.Origin == null || !e.Origin.IsSubclassOf(typeof(MultiView)))
return;
this.Messages.Add(e.MessageId);
}
public override void Init()
{
Device.MessageSent += Device_MessageSent;
}
public override async Task Load(MessageResult result)
{
_Rendered = false;
}
public override async Task Render(MessageResult result)
{
//When already rendered, skip rendering
if (_Rendered)
return;
await CleanUpView();
await RenderView(new RenderViewEventArgs(this.SelectedViewIndex));
_Rendered = true;
}
/// <summary>
/// Will get invoked on rendering the current controls view.
/// </summary>
/// <param name="e"></param>
public virtual async Task RenderView(RenderViewEventArgs e)
{
}
async Task CleanUpView()
{
var tasks = new List<Task>();
foreach (var msg in this.Messages)
{
tasks.Add(this.Device.DeleteMessage(msg));
}
await Task.WhenAll(tasks);
this.Messages.Clear();
}
/// <summary>
/// Forces render of control contents.
/// </summary>
public async Task ForceRender()
{
await CleanUpView();
await RenderView(new RenderViewEventArgs(this.SelectedViewIndex));
_Rendered = true;
}
public override async Task Cleanup()
{
Device.MessageSent -= Device_MessageSent;
await CleanUpView();
}
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
@ -258,8 +259,6 @@ namespace TelegramBotBase.Sessions
InlineKeyboardMarkup markup = buttons;
Message m = null;
if (text.Length > Constants.Telegram.MaxMessageLength)
{
throw new MaxLengthException(text.Length);
@ -272,16 +271,17 @@ namespace TelegramBotBase.Sessions
try
{
m = await API(a => a.SendTextMessageAsync(deviceId, text, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
var t = API(a => a.SendTextMessageAsync(deviceId, text, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
OnMessageSent(new MessageSentEventArgs(m));
var o = GetOrigin(new StackTrace());
OnMessageSent(new MessageSentEventArgs(await t, o));
return await t;
}
catch
{
return null;
}
return m;
}
/// <summary>
@ -310,8 +310,6 @@ namespace TelegramBotBase.Sessions
if (this.ActiveForm == null)
return null;
Message m = null;
if (text.Length > Constants.Telegram.MaxMessageLength)
{
throw new MaxLengthException(text.Length);
@ -324,16 +322,17 @@ namespace TelegramBotBase.Sessions
try
{
m = await API(a => a.SendTextMessageAsync(this.DeviceId, text, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
var t = API(a => a.SendTextMessageAsync(this.DeviceId, text, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
OnMessageSent(new MessageSentEventArgs(m));
var o = GetOrigin(new StackTrace());
OnMessageSent(new MessageSentEventArgs(await t, o));
return await t;
}
catch
{
return null;
}
return m;
}
/// <summary>
@ -349,8 +348,6 @@ namespace TelegramBotBase.Sessions
if (this.ActiveForm == null)
return null;
Message m = null;
if (text.Length > Constants.Telegram.MaxMessageLength)
{
throw new MaxLengthException(text.Length);
@ -363,16 +360,17 @@ namespace TelegramBotBase.Sessions
try
{
m = await API(a => a.SendTextMessageAsync(this.DeviceId, text, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
var t = API(a => a.SendTextMessageAsync(this.DeviceId, text, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
OnMessageSent(new MessageSentEventArgs(m));
var o = GetOrigin(new StackTrace());
OnMessageSent(new MessageSentEventArgs(await t, o));
return await t;
}
catch
{
return null;
}
return m;
}
/// <summary>
@ -390,20 +388,19 @@ namespace TelegramBotBase.Sessions
InlineKeyboardMarkup markup = buttons;
Message m = null;
try
{
m = await API(a => a.SendPhotoAsync(this.DeviceId, file, caption: caption, parseMode: parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
var t = API(a => a.SendPhotoAsync(this.DeviceId, file, caption: caption, parseMode: parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
OnMessageSent(new MessageSentEventArgs(m));
var o = GetOrigin(new StackTrace());
OnMessageSent(new MessageSentEventArgs(await t, o));
return await t;
}
catch
{
return null;
}
return m;
}
/// <summary>
@ -459,20 +456,19 @@ namespace TelegramBotBase.Sessions
InlineKeyboardMarkup markup = buttons;
Message m = null;
try
{
m = await API(a => a.SendVideoAsync(this.DeviceId, file, caption: caption, parseMode: parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
var t = API(a => a.SendVideoAsync(this.DeviceId, file, caption: caption, parseMode: parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
OnMessageSent(new MessageSentEventArgs(m));
var o = GetOrigin(new StackTrace());
OnMessageSent(new MessageSentEventArgs(await t, o));
return await t;
}
catch
{
return null;
}
return m;
}
/// <summary>
@ -490,20 +486,19 @@ namespace TelegramBotBase.Sessions
InlineKeyboardMarkup markup = buttons;
Message m = null;
try
{
m = await API(a => a.SendVideoAsync(this.DeviceId, new InputOnlineFile(url), parseMode: parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
var t = API(a => a.SendVideoAsync(this.DeviceId, new InputOnlineFile(url), parseMode: parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
OnMessageSent(new MessageSentEventArgs(m));
var o = GetOrigin(new StackTrace());
OnMessageSent(new MessageSentEventArgs(await t, o));
return await t;
}
catch
{
return null;
}
return m;
}
/// <summary>
@ -568,11 +563,19 @@ namespace TelegramBotBase.Sessions
markup = buttons;
}
var m = await API(a => a.SendDocumentAsync(this.DeviceId, document, caption, replyMarkup: markup, disableNotification: disableNotification, replyToMessageId: replyTo));
try
{
var t = API(a => a.SendDocumentAsync(this.DeviceId, document, caption, replyMarkup: markup, disableNotification: disableNotification, replyToMessageId: replyTo));
OnMessageSent(new MessageSentEventArgs(m));
var o = GetOrigin(new StackTrace());
OnMessageSent(new MessageSentEventArgs(await t, o));
return m;
return await t;
}
catch
{
return null;
}
}
/// <summary>
@ -677,6 +680,23 @@ namespace TelegramBotBase.Sessions
}
}
private Type GetOrigin(StackTrace stackTrace)
{
for (int i = 0; i < stackTrace.FrameCount; i++)
{
var methodBase = stackTrace.GetFrame(i).GetMethod();
//Debug.WriteLine(methodBase.Name);
if (methodBase.DeclaringType.IsSubclassOf(typeof(FormBase)) | methodBase.DeclaringType.IsSubclassOf(typeof(ControlBase)))
{
return methodBase.DeclaringType;
}
}
return null;
}
#region "Users"
public virtual async Task RestrictUser(int userId, ChatPermissions permissions, DateTime until = default(DateTime))

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.1;net461;netcoreapp3.1</TargetFrameworks>
<TargetFrameworks>netstandard2.1;net472;netcoreapp3.1</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
@ -84,7 +84,11 @@
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="System.Drawing.Common" Version="4.7.0" />
<PackageReference Include="Telegram.Bot" Version="15.5.1" />
<PackageReference Include="Telegram.Bot" Version="15.7.1" />
</ItemGroup>
<ItemGroup>
<Folder Include="Controls\Reply\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using TelegramBotBase.Base;
using TelegramBotBase.Controls.Hybrid;
using TelegramBotBase.Form;
namespace TelegramBotBaseTest.Tests.Controls
{
public class MultiViewForm : AutoCleanForm
{
Subclass.MultiViewTest mvt = null;
ButtonGrid bg = null;
public MultiViewForm()
{
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
this.Init += MultiViewForm_Init;
}
private async Task MultiViewForm_Init(object sender, TelegramBotBase.Args.InitEventArgs e)
{
mvt = new Subclass.MultiViewTest();
AddControl(mvt);
bg = new ButtonGrid();
bg.ButtonsForm = new ButtonForm();
bg.ButtonsForm.AddButtonRow("Back", "$back$");
bg.ButtonClicked += Bg_ButtonClicked;
bg.KeyboardType = TelegramBotBase.Enums.eKeyboardType.ReplyKeyboard;
AddControl(bg);
}
private async Task Bg_ButtonClicked(object sender, TelegramBotBase.Args.ButtonClickedEventArgs e)
{
switch(e.Button.Value)
{
case "$back$":
var mn = new Menu();
await NavigateTo(mn);
break;
}
}
public override async Task Load(MessageResult message)
{
}
public override async Task Action(MessageResult message)
{
}
public override async Task Render(MessageResult message)
{
}
}
}

View File

@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using TelegramBotBase.Args;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
namespace TelegramBotBaseTest.Tests.Controls.Subclass
{
public class MultiViewTest : TelegramBotBase.Controls.Hybrid.MultiView
{
public override async Task Action(MessageResult result, string value = null)
{
switch(result.RawData)
{
case "back":
this.SelectedViewIndex--;
break;
case "next":
this.SelectedViewIndex++;
break;
}
}
public override async Task RenderView(RenderViewEventArgs e)
{
ButtonForm bf = new ButtonForm();
bf.AddButtonRow(new ButtonBase("Back", "back"), new ButtonBase("Next", "next"));
switch(e.CurrentView)
{
case 0:
await Device.Send("Page 1", bf);
break;
case 1:
await Device.Send("Page 2", bf);
break;
case 2:
await Device.Send("Page 3", bf);
break;
default:
await Device.Send("Unknown Page", bf);
break;
}
}
}
}

View File

@ -5,6 +5,7 @@ using System.Text;
using System.Threading.Tasks;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
using TelegramBotBaseTest.Tests.Controls;
namespace TelegramBotBaseTest.Tests
{
@ -27,6 +28,7 @@ namespace TelegramBotBaseTest.Tests
}
await Device.HideReplyKeyboard();
}
public override async Task Action(MessageResult message)
@ -156,6 +158,17 @@ namespace TelegramBotBaseTest.Tests
await this.NavigateTo(bg2);
break;
case "multiview":
message.Handled = true;
var mvf = new MultiViewForm();
await NavigateTo(mvf);
break;
}
@ -187,6 +200,8 @@ namespace TelegramBotBaseTest.Tests
btn.AddButtonRow(new ButtonBase("#13 ButtonGrid Paging & Filter", new CallbackData("a", "buttongridfilter").Serialize()));
btn.AddButtonRow(new ButtonBase("#15 MultiView", new CallbackData("a", "multiview").Serialize()));
await this.Device.Send("Choose your test:", btn);
}