diff --git a/TelegramBotBase/Args/MessageSentEventArgs.cs b/TelegramBotBase/Args/MessageSentEventArgs.cs
index a57ea30..d096db1 100644
--- a/TelegramBotBase/Args/MessageSentEventArgs.cs
+++ b/TelegramBotBase/Args/MessageSentEventArgs.cs
@@ -19,9 +19,16 @@ namespace TelegramBotBase.Args
public Message Message { get; set; }
- public MessageSentEventArgs(Message message)
+ ///
+ /// Contains the element, which has called the method.
+ ///
+ public Type Origin { get; set; }
+
+
+ public MessageSentEventArgs(Message message, Type Origin)
{
this.Message = message;
+ this.Origin = Origin;
}
diff --git a/TelegramBotBase/Args/RenderViewEventArgs.cs b/TelegramBotBase/Args/RenderViewEventArgs.cs
new file mode 100644
index 0000000..a733291
--- /dev/null
+++ b/TelegramBotBase/Args/RenderViewEventArgs.cs
@@ -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;
+ }
+
+
+ }
+}
diff --git a/TelegramBotBase/Controls/Hybrid/MultiView.cs b/TelegramBotBase/Controls/Hybrid/MultiView.cs
new file mode 100644
index 0000000..69ec518
--- /dev/null
+++ b/TelegramBotBase/Controls/Hybrid/MultiView.cs
@@ -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
+{
+
+ ///
+ /// This Control is for having a basic form content switching control.
+ ///
+ public abstract class MultiView : Base.ControlBase
+ {
+ ///
+ /// Index of the current View.
+ ///
+ public int SelectedViewIndex
+ {
+ get
+ {
+ return m_iSelectedViewIndex;
+ }
+ set
+ {
+ m_iSelectedViewIndex = value;
+
+ //Already rendered? Re-Render
+ if (_Rendered)
+ ForceRender().Wait();
+ }
+ }
+
+ private int m_iSelectedViewIndex = 0;
+
+ ///
+ /// Hold if the View has been rendered already.
+ ///
+ private bool _Rendered = false;
+
+ private List Messages { get; set; }
+
+
+ public MultiView()
+ {
+ Messages = new List();
+ }
+
+
+ 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;
+ }
+
+
+ ///
+ /// Will get invoked on rendering the current controls view.
+ ///
+ ///
+ public virtual async Task RenderView(RenderViewEventArgs e)
+ {
+
+
+ }
+
+ async Task CleanUpView()
+ {
+
+ var tasks = new List();
+
+ foreach (var msg in this.Messages)
+ {
+ tasks.Add(this.Device.DeleteMessage(msg));
+ }
+
+ await Task.WhenAll(tasks);
+
+ this.Messages.Clear();
+
+ }
+
+ ///
+ /// Forces render of control contents.
+ ///
+ 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();
+ }
+
+ }
+}
diff --git a/TelegramBotBase/Sessions/DeviceSession.cs b/TelegramBotBase/Sessions/DeviceSession.cs
index 4c83895..12d57d4 100644
--- a/TelegramBotBase/Sessions/DeviceSession.cs
+++ b/TelegramBotBase/Sessions/DeviceSession.cs
@@ -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;
}
///
@@ -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;
}
///
@@ -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;
}
///
@@ -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;
}
///
@@ -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;
}
///
@@ -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;
}
///
@@ -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;
+ }
}
///
@@ -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))
diff --git a/TelegramBotBase/TelegramBotBase.csproj b/TelegramBotBase/TelegramBotBase.csproj
index dc41769..51d72f9 100644
--- a/TelegramBotBase/TelegramBotBase.csproj
+++ b/TelegramBotBase/TelegramBotBase.csproj
@@ -1,7 +1,7 @@
- netstandard2.1;net461;netcoreapp3.1
+ netstandard2.1;net472;netcoreapp3.1
false
false
true
@@ -84,7 +84,11 @@
-
+
+
+
+
+
diff --git a/TelegramBotBaseTest/Tests/Controls/MultiViewForm.cs b/TelegramBotBaseTest/Tests/Controls/MultiViewForm.cs
new file mode 100644
index 0000000..543b3c5
--- /dev/null
+++ b/TelegramBotBaseTest/Tests/Controls/MultiViewForm.cs
@@ -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)
+ {
+
+ }
+
+
+
+ }
+}
diff --git a/TelegramBotBaseTest/Tests/Controls/Subclass/MultiViewTest.cs b/TelegramBotBaseTest/Tests/Controls/Subclass/MultiViewTest.cs
new file mode 100644
index 0000000..cc2812d
--- /dev/null
+++ b/TelegramBotBaseTest/Tests/Controls/Subclass/MultiViewTest.cs
@@ -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;
+
+
+ }
+
+ }
+
+
+
+ }
+}
diff --git a/TelegramBotBaseTest/Tests/Menu.cs b/TelegramBotBaseTest/Tests/Menu.cs
index f3f6de1..28bdb68 100644
--- a/TelegramBotBaseTest/Tests/Menu.cs
+++ b/TelegramBotBaseTest/Tests/Menu.cs
@@ -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);
}