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); }