Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5893108bd3 | ||
|
|
d668f57711 | ||
|
|
56c7754408 | ||
|
|
805ffb9ec7 | ||
|
|
aeddd82ea9 | ||
|
|
1ec14ce680 | ||
|
|
3a309baeae | ||
|
|
e02af0fc76 | ||
|
|
530e01f971 | ||
|
|
dcf3cf804f | ||
|
|
a42d3934b5 | ||
|
|
2126b45fed | ||
|
|
b6b9d5b6b1 | ||
|
|
eed5f012dc | ||
|
|
de4cc138ae | ||
|
|
e4da70d37d | ||
|
|
cb4a797b12 | ||
|
|
94d153e141 | ||
|
|
e13cb6d4ef | ||
|
|
c0e285d39e | ||
|
|
8338c5c066 | ||
|
|
52c01b3dfd | ||
|
|
fe1aafc9a5 | ||
|
|
022eee4b57 | ||
|
|
ea971979e2 | ||
|
|
9585a231bd | ||
|
|
c07aca96a4 | ||
|
|
01de9ec932 | ||
|
|
94fe263676 | ||
|
|
4f1eae543d | ||
|
|
1491fc1795 |
@@ -1,14 +1,19 @@
|
||||
|
||||
|
||||
# .Net Telegram Bot Framework - Context based addon
|
||||
|
||||
[](https://www.nuget.org/packages/TelegramBotBase/)
|
||||
[](https://t.me/tgbotbase)
|
||||
[](https://www.t.me/tgbotbase)
|
||||
|
||||
|
||||
[](https://raw.githubusercontent.com/MajMcCloud/TelegramBotFramework/master/LICENCE.md)
|
||||
[](https://www.nuget.org/packages/TelegramBotBase)
|
||||
|
||||
Test the Testproject: [@TGBaseBot](https://t.me/TGBaseBot)
|
||||
Test the Testproject: [@TGBaseBot](https://www.t.me/TGBaseBot)
|
||||
|
||||
Join the Telegram Group: [https://www.t.me/tgbotbase](https://www.t.me/tgbotbase)
|
||||
|
||||
Download a release: [Releases](https://github.com/MajMcCloud/TelegramBotFramework/releases)
|
||||
|
||||
---
|
||||
|
||||
@@ -34,6 +39,16 @@ Test the Testproject: [@TGBaseBot](https://t.me/TGBaseBot)
|
||||
|
||||
* [PromptDialog](#prompt-dialog)
|
||||
|
||||
- [Controls](#controls)
|
||||
* [ProgressBar](#progress-bar)
|
||||
|
||||
* [CalendarPicker](#calendar-picker)
|
||||
|
||||
* [MonthPicker](#month-picker)
|
||||
|
||||
* [TreeView](#tree-view)
|
||||
|
||||
* [ToggleButton](#toggle-button)
|
||||
|
||||
---
|
||||
|
||||
@@ -217,15 +232,20 @@ On every input the user is sending back to the bot the Action event gets raised.
|
||||
|
||||
### Lets start with text messages (Example #1 - Simple Test)
|
||||
|
||||
|
||||
<img src="images/example1.PNG" />
|
||||
|
||||
```
|
||||
public class SimpleForm : FormBase
|
||||
public class SimpleForm : AutoCleanForm
|
||||
{
|
||||
|
||||
public SimpleForm()
|
||||
{
|
||||
this.DeleteSide = eSide.Both;
|
||||
this.DeleteMode = eDeleteMode.OnLeavingForm;
|
||||
}
|
||||
|
||||
public override async Task Opened()
|
||||
{
|
||||
await this.Device.Send("Hello world!");
|
||||
await this.Device.Send("Hello world! (send 'back' to get back to Start)\r\nOr\r\nhi, hello, maybe, bye and ciao");
|
||||
}
|
||||
|
||||
|
||||
@@ -267,6 +287,7 @@ public class SimpleForm : FormBase
|
||||
|
||||
I using a different base class (AutoCleanForm) I created for a better "feeling" inside the bot which will delete "old" messages from this form. You have some settings within this class to manage when messages should be getting deleted.
|
||||
|
||||
<img src="images/example2.PNG" />
|
||||
|
||||
```
|
||||
public class ButtonTestForm : AutoCleanForm
|
||||
@@ -344,6 +365,8 @@ public class ButtonTestForm : AutoCleanForm
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Button 3", new CallbackData("a", "button3").Serialize()), new ButtonBase("Button 4", new CallbackData("a", "button4").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Google.com", "google", "https://www.google.com"), new ButtonBase("Telegram", "telegram", "https://telegram.org/"));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Back", new CallbackData("a", "back").Serialize()));
|
||||
|
||||
await this.Device.Send("Click a button", btn);
|
||||
@@ -359,6 +382,8 @@ public class ButtonTestForm : AutoCleanForm
|
||||
Sometimes it makes sense to show the end user a type of progressbar or status. For this i tried to make a simple control, which is useful for some situations.
|
||||
Maybe, if i got more ideas, i will add other "controls" in the future.
|
||||
|
||||
<img src="images/example3.PNG" />
|
||||
|
||||
```
|
||||
|
||||
public class ProgressTest : AutoCleanForm
|
||||
@@ -493,6 +518,14 @@ public override async Task Closed()
|
||||
I read it a lot in different Telegram groups that some developers are searching for easy solutions to create context based apps. For this is my project an ideal solution here.
|
||||
To give you an example about the possiblities, i added into the Test project an example for a registration form.
|
||||
|
||||
<img src="images/example4.1.PNG" />
|
||||
|
||||
<img src="images/example4.2.PNG" />
|
||||
|
||||
<img src="images/example4.3.PNG" />
|
||||
|
||||
<img src="images/example4.4.PNG" />
|
||||
|
||||
```
|
||||
|
||||
public class PerForm : AutoCleanForm
|
||||
@@ -615,6 +648,8 @@ For now we have the following:
|
||||
|
||||
### Alert Dialog
|
||||
|
||||
<img src="images/alertdialog.PNG" />
|
||||
|
||||
```
|
||||
|
||||
var fto = new TestForm2();
|
||||
@@ -628,10 +663,12 @@ await this.NavigateTo(ad);
|
||||
|
||||
### AutoCleanForm
|
||||
|
||||
|
||||
No example yet
|
||||
|
||||
### Prompt Dialog
|
||||
|
||||
<img src="images/promptdialog.PNG" />
|
||||
|
||||
#### Without Eventhandler (pre-init of form necessary)
|
||||
|
||||
```
|
||||
@@ -669,6 +706,34 @@ await this.NavigateTo(pd);
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Controls
|
||||
|
||||
### Progress Bar
|
||||
<img src="images/progressbar.PNG?raw=true" />
|
||||
|
||||
|
||||
### Calendar Picker
|
||||
<img src="images/calendarpicker.PNG?raw=true" />
|
||||
|
||||
<img src="images/calendarpicker.gif?raw=true" />
|
||||
|
||||
### Month Picker
|
||||
<img src="images/monthpicker1.PNG?raw=true" />
|
||||
<img src="images/monthpicker2.PNG?raw=true" />
|
||||
|
||||
|
||||
### Tree View
|
||||
<img src="images/treeview1.PNG?raw=true" />
|
||||
<img src="images/treeview2.PNG?raw=true" />
|
||||
<img src="images/treeview3.PNG?raw=true" />
|
||||
<img src="images/treeview4.PNG?raw=true" />
|
||||
|
||||
|
||||
### Toggle Button
|
||||
<img src="images/togglebutton.gif?raw=true" />
|
||||
|
||||
---
|
||||
|
||||
I will add more notes to it soon, so stay tuned.
|
||||
|
||||
@@ -11,7 +11,12 @@ namespace TelegramBaseTest.Tests
|
||||
public class ButtonTestForm : AutoCleanForm
|
||||
{
|
||||
|
||||
public override async Task Opened()
|
||||
public ButtonTestForm()
|
||||
{
|
||||
this.Opened += ButtonTestForm_Opened;
|
||||
}
|
||||
|
||||
private async Task ButtonTestForm_Opened(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Hello world! (Click 'back' to get back to Start)");
|
||||
}
|
||||
@@ -83,6 +88,8 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Button 3", new CallbackData("a", "button3").Serialize()), new ButtonBase("Button 4", new CallbackData("a", "button4").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Google.com", "google", "https://www.google.com"), new ButtonBase("Telegram", "telegram", "https://telegram.org/"));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Back", new CallbackData("a", "back").Serialize()));
|
||||
|
||||
await this.Device.Send("Click a button", btn);
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
using TelegramBotBase.Controls;
|
||||
|
||||
namespace TelegramBaseTest.Tests.Controls
|
||||
{
|
||||
public class CalendarPickerForm : AutoCleanForm
|
||||
{
|
||||
|
||||
public CalendarPicker Picker { get; set; }
|
||||
|
||||
int? selectedDateMessage { get; set; }
|
||||
|
||||
public CalendarPickerForm()
|
||||
{
|
||||
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
|
||||
this.Init += CalendarPickerForm_Init;
|
||||
}
|
||||
|
||||
private async Task CalendarPickerForm_Init(object sender, InitEventArgs e)
|
||||
{
|
||||
this.Picker = new CalendarPicker();
|
||||
this.Picker.Title = "Datum auswählen / Pick date";
|
||||
|
||||
this.AddControl(Picker);
|
||||
}
|
||||
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
|
||||
switch(message.RawData)
|
||||
{
|
||||
case "back":
|
||||
|
||||
var s = new Start();
|
||||
|
||||
await this.NavigateTo(s);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
String s = "";
|
||||
|
||||
s = "Selected date is " + this.Picker.SelectedDate.ToShortDateString() + "\r\n";
|
||||
s += "Selected month is " + this.Picker.Culture.DateTimeFormat.MonthNames[this.Picker.VisibleMonth.Month - 1] + "\r\n";
|
||||
s += "Selected year is " + this.Picker.VisibleMonth.Year.ToString();
|
||||
|
||||
ButtonForm bf = new ButtonForm();
|
||||
bf.AddButtonRow(new ButtonBase("Back","back"));
|
||||
|
||||
if (selectedDateMessage != null)
|
||||
{
|
||||
await this.Device.Edit(this.selectedDateMessage.Value, s, bf);
|
||||
}
|
||||
else
|
||||
{
|
||||
var m = await this.Device.Send(s, bf);
|
||||
this.selectedDateMessage = m.MessageId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
using TelegramBotBase.Controls;
|
||||
|
||||
namespace TelegramBaseTest.Tests.Controls
|
||||
{
|
||||
public class MonthPickerForm : AutoCleanForm
|
||||
{
|
||||
|
||||
public MonthPicker Picker { get; set; }
|
||||
|
||||
int? selectedDateMessage { get; set; }
|
||||
|
||||
public MonthPickerForm()
|
||||
{
|
||||
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
|
||||
this.Init += MonthPickerForm_Init;
|
||||
}
|
||||
|
||||
private async Task MonthPickerForm_Init(object sender, InitEventArgs e)
|
||||
{
|
||||
this.Picker = new MonthPicker();
|
||||
this.Picker.Title = "Monat auswählen / Pick month";
|
||||
this.AddControl(Picker);
|
||||
}
|
||||
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
|
||||
switch(message.RawData)
|
||||
{
|
||||
case "back":
|
||||
|
||||
var s = new Start();
|
||||
|
||||
await this.NavigateTo(s);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
String s = "";
|
||||
|
||||
s += "Selected month is " + this.Picker.Culture.DateTimeFormat.MonthNames[this.Picker.SelectedDate.Month - 1] + "\r\n";
|
||||
s += "Selected year is " + this.Picker.VisibleMonth.Year.ToString();
|
||||
|
||||
ButtonForm bf = new ButtonForm();
|
||||
bf.AddButtonRow(new ButtonBase("Back","back"));
|
||||
|
||||
if (selectedDateMessage != null)
|
||||
{
|
||||
await this.Device.Edit(this.selectedDateMessage.Value, s, bf);
|
||||
}
|
||||
else
|
||||
{
|
||||
var m = await this.Device.Send(s, bf);
|
||||
this.selectedDateMessage = m.MessageId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Controls;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBaseTest.Tests.Controls
|
||||
{
|
||||
public class ToggleButtons : AutoCleanForm
|
||||
{
|
||||
public ToggleButtons()
|
||||
{
|
||||
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
|
||||
|
||||
this.Init += ToggleButtons_Init;
|
||||
}
|
||||
|
||||
private async Task ToggleButtons_Init(object sender, TelegramBotBase.Base.InitEventArgs e)
|
||||
{
|
||||
|
||||
var tb = new ToggleButton();
|
||||
tb.Checked = true;
|
||||
tb.Toggled += Tb_Toggled;
|
||||
|
||||
this.AddControl(tb);
|
||||
|
||||
tb = new ToggleButton();
|
||||
tb.Checked = false;
|
||||
tb.Toggled += Tb_Toggled;
|
||||
|
||||
this.AddControl(tb);
|
||||
|
||||
tb = new ToggleButton();
|
||||
tb.Checked = true;
|
||||
tb.Toggled += Tb_Toggled;
|
||||
|
||||
this.AddControl(tb);
|
||||
|
||||
}
|
||||
|
||||
private void Tb_Toggled(object sender, EventArgs e)
|
||||
{
|
||||
var tb = sender as ToggleButton;
|
||||
Console.WriteLine(tb.ID.ToString() + " was pressed, and toggled to " + (tb.Checked ? "Checked" : "Unchecked"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Form;
|
||||
using TelegramBotBase.Controls;
|
||||
using TelegramBotBase.Base;
|
||||
|
||||
namespace TelegramBaseTest.Tests.Controls
|
||||
{
|
||||
public class TreeViewForms : AutoCleanForm
|
||||
{
|
||||
public TreeView view { get; set; }
|
||||
|
||||
private int? MessageId { get; set; }
|
||||
|
||||
public TreeViewForms()
|
||||
{
|
||||
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
|
||||
this.Init += TreeViewForms_Init;
|
||||
}
|
||||
|
||||
private async Task TreeViewForms_Init(object sender, TelegramBotBase.Base.InitEventArgs e)
|
||||
{
|
||||
view = new TreeView();
|
||||
|
||||
var tvn = new TreeViewNode("Cars", "cars");
|
||||
|
||||
tvn.AddNode(new TreeViewNode("Porsche", "porsche", new TreeViewNode("Website", "web", "https://www.porsche.com/germany/"), new TreeViewNode("911", "911"), new TreeViewNode("918 Spyder", "918")));
|
||||
tvn.AddNode(new TreeViewNode("BMW", "bmw"));
|
||||
tvn.AddNode(new TreeViewNode("Audi", "audi"));
|
||||
tvn.AddNode(new TreeViewNode("VW", "vw"));
|
||||
tvn.AddNode(new TreeViewNode("Lamborghini", "lamborghini"));
|
||||
|
||||
view.Nodes.Add(tvn);
|
||||
|
||||
tvn = new TreeViewNode("Fruits", "fruits");
|
||||
|
||||
tvn.AddNode(new TreeViewNode("Apple", "apple"));
|
||||
tvn.AddNode(new TreeViewNode("Orange", "orange"));
|
||||
tvn.AddNode(new TreeViewNode("Lemon", "lemon"));
|
||||
|
||||
view.Nodes.Add(tvn);
|
||||
|
||||
this.AddControl(view);
|
||||
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
await message.ConfirmAction();
|
||||
|
||||
if (message.Handled)
|
||||
return;
|
||||
|
||||
switch (message.RawData)
|
||||
{
|
||||
case "back":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var start = new Start();
|
||||
|
||||
await this.NavigateTo(start);
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
String s = "";
|
||||
|
||||
s += "Selected Node: " + (this.view.SelectedNode?.Text ?? "(null)") + "\r\n";
|
||||
|
||||
s += "Visible Node: " + (this.view.VisibleNode?.Text ?? "(top)") + "\r\n";
|
||||
|
||||
s += "Visible Path: " + this.view.GetPath() + "\r\n";
|
||||
s += "Selected Path: " + (this.view.SelectedNode?.GetPath() ?? "(null)") + "\r\n";
|
||||
|
||||
ButtonForm bf = new ButtonForm();
|
||||
bf.AddButtonRow(new ButtonBase("Back", "back"));
|
||||
|
||||
if (MessageId != null)
|
||||
{
|
||||
await this.Device.Edit(this.MessageId.Value, s, bf);
|
||||
}
|
||||
else
|
||||
{
|
||||
var m = await this.Device.Send(s, bf);
|
||||
this.MessageId = m.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -14,10 +14,13 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
public ProgressTest()
|
||||
{
|
||||
this.DeleteMode = eDeleteMode.OnLeavingForm;
|
||||
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
|
||||
this.Opened += ProgressTest_Opened;
|
||||
this.Closed += ProgressTest_Closed;
|
||||
}
|
||||
|
||||
public override async Task Opened()
|
||||
|
||||
private async Task ProgressTest_Opened(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Welcome to ProgressTest");
|
||||
}
|
||||
@@ -87,14 +90,14 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
|
||||
//Render Progress bar and show some "example" progress
|
||||
await Bar.Render();
|
||||
await Bar.Render(message);
|
||||
|
||||
this.Controls.Add(Bar);
|
||||
|
||||
for (int i = 0; i <= 100; i++)
|
||||
{
|
||||
Bar.Value++;
|
||||
await Bar.Render();
|
||||
await Bar.Render(message);
|
||||
|
||||
Thread.Sleep(250);
|
||||
}
|
||||
@@ -117,17 +120,10 @@ namespace TelegramBaseTest.Tests
|
||||
await this.Device.Send("Choose your progress bar:", btn);
|
||||
}
|
||||
|
||||
public override async Task Closed()
|
||||
private async Task ProgressTest_Closed(object sender, EventArgs e)
|
||||
{
|
||||
foreach (var b in this.Controls)
|
||||
{
|
||||
await b.Cleanup();
|
||||
}
|
||||
|
||||
await this.Device.Send("Ciao from ProgressTest");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,17 @@ namespace TelegramBaseTest.Tests.Register.Steps
|
||||
{
|
||||
public Data UserData { get; set; }
|
||||
|
||||
public async override Task Init(params object[] args)
|
||||
public Step1()
|
||||
{
|
||||
this.Init += Step1_Init;
|
||||
}
|
||||
|
||||
private async Task Step1_Init(object sender, InitEventArgs e)
|
||||
{
|
||||
this.UserData = new Data();
|
||||
}
|
||||
|
||||
|
||||
public async override Task Load(MessageResult message)
|
||||
{
|
||||
if (message.Handled)
|
||||
|
||||
@@ -8,14 +8,21 @@ using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBaseTest.Tests
|
||||
{
|
||||
public class SimpleForm : FormBase
|
||||
public class SimpleForm : AutoCleanForm
|
||||
{
|
||||
|
||||
public override async Task Opened()
|
||||
public SimpleForm()
|
||||
{
|
||||
await this.Device.Send("Hello world! (send 'back' to get back to Start)");
|
||||
this.DeleteSide = TelegramBotBase.Enums.eSide.Both;
|
||||
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
|
||||
|
||||
this.Opened += SimpleForm_Opened;
|
||||
}
|
||||
|
||||
private async Task SimpleForm_Opened(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Hello world! (send 'back' to get back to Start)\r\nOr\r\nhi, hello, maybe, bye and ciao");
|
||||
}
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
|
||||
@@ -8,8 +8,12 @@ using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBaseTest.Tests
|
||||
{
|
||||
public class Start : FormBase
|
||||
public class Start : AutoCleanForm
|
||||
{
|
||||
public Start()
|
||||
{
|
||||
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
@@ -79,6 +83,46 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
await this.NavigateTo(data);
|
||||
|
||||
break;
|
||||
|
||||
case "calendar":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var calendar = new Controls.CalendarPickerForm();
|
||||
|
||||
await this.NavigateTo(calendar);
|
||||
|
||||
break;
|
||||
|
||||
case "month":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var month = new Controls.MonthPickerForm();
|
||||
|
||||
await this.NavigateTo(month);
|
||||
|
||||
break;
|
||||
|
||||
case "treeview":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var tree = new Controls.TreeViewForms();
|
||||
|
||||
await this.NavigateTo(tree);
|
||||
|
||||
break;
|
||||
|
||||
case "togglebuttons":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var tb = new Controls.ToggleButtons();
|
||||
|
||||
await this.NavigateTo(tb);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -99,6 +143,12 @@ namespace TelegramBaseTest.Tests
|
||||
btn.AddButtonRow(new ButtonBase("#6 Form2 Command", new CallbackData("a", "form2").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("#7 Data Handling", new CallbackData("a", "data").Serialize()));
|
||||
btn.AddButtonRow(new ButtonBase("#8 Calendar Picker", new CallbackData("a", "calendar").Serialize()));
|
||||
btn.AddButtonRow(new ButtonBase("#9 Month Picker", new CallbackData("a", "month").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("#10 TreeView", new CallbackData("a", "treeview").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("#11 ToggleButtons", new CallbackData("a", "togglebuttons").Serialize()));
|
||||
|
||||
await this.Device.Send("Choose your test:", btn);
|
||||
}
|
||||
|
||||
@@ -15,27 +15,22 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
String LastMessage { get; set; }
|
||||
|
||||
public override async Task Init(params object[] param)
|
||||
public TestForm()
|
||||
{
|
||||
|
||||
this.Opened += TestForm_Opened;
|
||||
this.Closed += TestForm_Closed;
|
||||
}
|
||||
|
||||
public override async Task Opened()
|
||||
private async Task TestForm_Opened(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Welcome to Form 1");
|
||||
}
|
||||
|
||||
public override async Task Closed()
|
||||
private async Task TestForm_Closed(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Ciao from Form 1");
|
||||
}
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
|
||||
@@ -15,25 +15,25 @@ namespace TelegramBaseTest.Tests
|
||||
public class TestForm2 : FormBase
|
||||
{
|
||||
|
||||
public override async Task Init(params object[] param)
|
||||
{
|
||||
|
||||
public TestForm2()
|
||||
{
|
||||
this.Opened += TestForm2_Opened;
|
||||
this.Closed += TestForm2_Closed;
|
||||
}
|
||||
|
||||
public override async Task Opened()
|
||||
private async Task TestForm2_Opened(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Welcome to Form 2");
|
||||
}
|
||||
|
||||
public override async Task Closed()
|
||||
private async Task TestForm2_Closed(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Ciao from Form 2");
|
||||
}
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="12.0.1" targetFramework="net452" />
|
||||
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net452" />
|
||||
<package id="System.Net.Requests" version="4.3.0" targetFramework="net452" />
|
||||
<package id="Telegram.Bot" version="14.10.0" targetFramework="net452" />
|
||||
<package id="Telegram.Bot" version="14.12.0" targetFramework="net452" />
|
||||
</packages>
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
{
|
||||
public static class Async
|
||||
{
|
||||
public delegate Task AsyncEventHandler<TEventArgs>(object sender, TEventArgs e) where TEventArgs : EventArgs;
|
||||
|
||||
public static IEnumerable<AsyncEventHandler<TEventArgs>> GetHandlers<TEventArgs>(
|
||||
this AsyncEventHandler<TEventArgs> handler)
|
||||
where TEventArgs : EventArgs
|
||||
=> handler.GetInvocationList().Cast<AsyncEventHandler<TEventArgs>>();
|
||||
|
||||
public static Task InvokeAllAsync<TEventArgs>(this AsyncEventHandler<TEventArgs> handler, object sender, TEventArgs e)
|
||||
where TEventArgs : EventArgs
|
||||
=> Task.WhenAll(
|
||||
handler.GetHandlers()
|
||||
.Select(handleAsync => handleAsync(sender, e)));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,35 @@ namespace TelegramBotBase.Base
|
||||
{
|
||||
public Sessions.DeviceSession Device { get; set; }
|
||||
|
||||
public virtual async Task Render()
|
||||
public int ID { get; set; }
|
||||
|
||||
public String ControlID
|
||||
{
|
||||
get
|
||||
{
|
||||
return "#c" + this.ID.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines if the control should be rendered and invoked with actions
|
||||
/// </summary>
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
public virtual async Task Action(MessageResult result, String value = null)
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public virtual async Task Render(MessageResult result)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Sessions;
|
||||
using static TelegramBotBase.Base.Async;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
{
|
||||
@@ -13,47 +15,131 @@ namespace TelegramBotBase.Form
|
||||
/// </summary>
|
||||
public class FormBase : IDisposable
|
||||
{
|
||||
|
||||
public DeviceSession Device { get; set; }
|
||||
|
||||
public MessageClient Client { get; set; }
|
||||
|
||||
public bool CustomEventManagement { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// contains if the form has been switched (navigated)
|
||||
/// has this formular already been disposed ?
|
||||
/// </summary>
|
||||
public bool FormSwitched { get; set; } = false;
|
||||
public bool IsDisposed { get; set; } = false;
|
||||
|
||||
public List<ControlBase> Controls { get; set; }
|
||||
|
||||
|
||||
private EventHandlerList Events = new EventHandlerList();
|
||||
|
||||
|
||||
private static object __evInit = new object();
|
||||
|
||||
private static object __evOpened = new object();
|
||||
|
||||
private static object __evClosed = new object();
|
||||
|
||||
|
||||
public FormBase()
|
||||
{
|
||||
this.Controls = new List<Base.ControlBase>();
|
||||
}
|
||||
|
||||
public FormBase(MessageClient Client): this()
|
||||
public FormBase(MessageClient Client) : this()
|
||||
{
|
||||
this.Client = Client;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will get called at the initialization (once per context)
|
||||
/// </summary>
|
||||
public virtual async Task Init(params object[] args)
|
||||
|
||||
public async Task OnInit(InitEventArgs e)
|
||||
{
|
||||
|
||||
if (this.Events[__evInit] == null)
|
||||
return;
|
||||
|
||||
var handler = this.Events[__evInit].GetInvocationList().Cast<AsyncEventHandler<InitEventArgs>>();
|
||||
foreach (var h in handler)
|
||||
{
|
||||
await Async.InvokeAllAsync<InitEventArgs>(h, this, e);
|
||||
}
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// Will get called at the initialization (once per context)
|
||||
///// </summary>
|
||||
public event AsyncEventHandler<InitEventArgs> Init
|
||||
{
|
||||
add
|
||||
{
|
||||
this.Events.AddHandler(__evInit, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
this.Events.RemoveHandler(__evInit, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task OnOpened(EventArgs e)
|
||||
{
|
||||
if (this.Events[__evOpened] == null)
|
||||
return;
|
||||
|
||||
var handler = this.Events[__evOpened].GetInvocationList().Cast<AsyncEventHandler<EventArgs>>();
|
||||
foreach (var h in handler)
|
||||
{
|
||||
await Async.InvokeAllAsync<EventArgs>(h, this, e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets invoked if gets navigated to this form
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual async Task Opened()
|
||||
public event AsyncEventHandler<EventArgs> Opened
|
||||
{
|
||||
|
||||
add
|
||||
{
|
||||
this.Events.AddHandler(__evOpened, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
this.Events.RemoveHandler(__evOpened, value);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual async Task Closed()
|
||||
public async Task OnClosed(EventArgs e)
|
||||
{
|
||||
if (this.Events[__evClosed] == null)
|
||||
return;
|
||||
|
||||
var handler = this.Events[__evClosed].GetInvocationList().Cast<AsyncEventHandler<EventArgs>>();
|
||||
foreach (var h in handler)
|
||||
{
|
||||
await Async.InvokeAllAsync<EventArgs>(h, this, e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Form has been closed (left)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public event AsyncEventHandler<EventArgs> Closed
|
||||
{
|
||||
add
|
||||
{
|
||||
this.Events.AddHandler(__evClosed, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
this.Events.RemoveHandler(__evClosed, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Pre to form close, cleanup all controls
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task CloseControls()
|
||||
{
|
||||
foreach (var b in this.Controls)
|
||||
{
|
||||
@@ -76,6 +162,33 @@ namespace TelegramBotBase.Form
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets invoked if the user clicked a button.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public async Task ActionControls(MessageResult message)
|
||||
{
|
||||
//Looking for the control by id, if not listened, raise event for all
|
||||
if (message.RawData.StartsWith("#c"))
|
||||
{
|
||||
var c = this.Controls.FirstOrDefault(a => a.ControlID == message.RawData.Split('_')[0]);
|
||||
if (c != null)
|
||||
{
|
||||
await c.Action(message, message.RawData.Split('_')[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var b in this.Controls)
|
||||
{
|
||||
if (!b.Enabled)
|
||||
continue;
|
||||
|
||||
await b.Action(message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets invoked if the user has clicked a button.
|
||||
/// </summary>
|
||||
@@ -96,6 +209,22 @@ namespace TelegramBotBase.Form
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets invoked at the end of the cycle to "Render" text, images, buttons, etc...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public async Task RenderControls(MessageResult message)
|
||||
{
|
||||
foreach (var b in this.Controls)
|
||||
{
|
||||
if (!b.Enabled)
|
||||
continue;
|
||||
|
||||
await b.Render(message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets invoked at the end of the cycle to "Render" text, images, buttons, etc...
|
||||
/// </summary>
|
||||
@@ -106,6 +235,8 @@ namespace TelegramBotBase.Form
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Navigates to a new form
|
||||
/// </summary>
|
||||
@@ -117,17 +248,28 @@ namespace TelegramBotBase.Form
|
||||
if (ds == null)
|
||||
return;
|
||||
|
||||
this.FormSwitched = true;
|
||||
ds.FormSwitched = true;
|
||||
|
||||
ds.PreviousForm = ds.ActiveForm;
|
||||
|
||||
ds.ActiveForm = newForm;
|
||||
newForm.Client = this.Client;
|
||||
newForm.Device = ds;
|
||||
|
||||
await newForm.Init(args);
|
||||
await newForm.OnInit(new InitEventArgs(args));
|
||||
|
||||
await this.Closed();
|
||||
await this.CloseControls();
|
||||
|
||||
await newForm.Opened();
|
||||
await this.OnClosed(new EventArgs());
|
||||
|
||||
await newForm.OnOpened(new EventArgs());
|
||||
}
|
||||
|
||||
public void AddControl(ControlBase control)
|
||||
{
|
||||
control.ID = this.Controls.Count + 1;
|
||||
control.Device = this.Device;
|
||||
this.Controls.Add(control);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -137,7 +279,7 @@ namespace TelegramBotBase.Form
|
||||
{
|
||||
this.Client = null;
|
||||
this.Device = null;
|
||||
this.FormSwitched = false;
|
||||
this.IsDisposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
{
|
||||
public class InitEventArgs : EventArgs
|
||||
{
|
||||
public object[] Args { get; set; }
|
||||
|
||||
public InitEventArgs(params object[] args)
|
||||
{
|
||||
this.Args = args;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
{
|
||||
public class MessageReceivedEventArgs
|
||||
{
|
||||
public int MessageId
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Message.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
public Message Message { get; set; }
|
||||
|
||||
public MessageReceivedEventArgs(Message m)
|
||||
{
|
||||
this.Message = m;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Sessions;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
{
|
||||
@@ -23,6 +24,9 @@ namespace TelegramBotBase.Base
|
||||
}
|
||||
}
|
||||
|
||||
public DeviceSession Device
|
||||
{ get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The message id
|
||||
/// </summary>
|
||||
|
||||
@@ -9,18 +9,18 @@ namespace TelegramBotBase.Base
|
||||
{
|
||||
public class MessageSentEventArgs
|
||||
{
|
||||
public int MessageId { get; set; }
|
||||
public int MessageId
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Message.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
public Message Message { get; set; }
|
||||
|
||||
public MessageSentEventArgs()
|
||||
public MessageSentEventArgs(Message message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public MessageSentEventArgs(int MessageId, Message message)
|
||||
{
|
||||
this.MessageId = MessageId;
|
||||
this.Message = message;
|
||||
}
|
||||
|
||||
|
||||
@@ -201,12 +201,15 @@ namespace TelegramBotBase
|
||||
|
||||
try
|
||||
{
|
||||
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
|
||||
e.Device = ds;
|
||||
|
||||
if (LogAllMessages)
|
||||
{
|
||||
DeviceSession ds2 = this.Sessions.GetSession(e.DeviceId);
|
||||
OnMessage(new MessageIncomeResult(e.DeviceId, ds2, e));
|
||||
OnMessage(new MessageIncomeResult(e.DeviceId, ds, e));
|
||||
}
|
||||
|
||||
ds?.OnMessageReceived(new MessageReceivedEventArgs(e.Message));
|
||||
|
||||
Client_TryMessage(sender, e);
|
||||
}
|
||||
@@ -223,10 +226,11 @@ namespace TelegramBotBase
|
||||
|
||||
private async void Client_TryMessage(object sender, MessageResult e)
|
||||
{
|
||||
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
|
||||
DeviceSession ds = e.Device;
|
||||
if (ds == null)
|
||||
{
|
||||
ds = await this.Sessions.StartSession<T>(e.DeviceId);
|
||||
e.Device = ds;
|
||||
|
||||
ds.LastMessage = e.Message;
|
||||
|
||||
@@ -255,11 +259,10 @@ namespace TelegramBotBase
|
||||
{
|
||||
i++;
|
||||
|
||||
activeForm = ds.ActiveForm;
|
||||
//Reset navigation
|
||||
ds.FormSwitched = false;
|
||||
|
||||
//If the form manages the events by itselfs, skip here
|
||||
if (activeForm.CustomEventManagement)
|
||||
return;
|
||||
activeForm = ds.ActiveForm;
|
||||
|
||||
//Pre Loading Event
|
||||
await activeForm.PreLoad(e);
|
||||
@@ -275,10 +278,10 @@ namespace TelegramBotBase
|
||||
}
|
||||
|
||||
//Render Event
|
||||
if (!activeForm.FormSwitched)
|
||||
if (!ds.FormSwitched)
|
||||
await activeForm.Render(e);
|
||||
|
||||
} while (activeForm.FormSwitched && i < NavigationMaximum);
|
||||
} while (ds.FormSwitched && i < NavigationMaximum);
|
||||
|
||||
}
|
||||
|
||||
@@ -286,10 +289,12 @@ namespace TelegramBotBase
|
||||
{
|
||||
try
|
||||
{
|
||||
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
|
||||
e.Device = ds;
|
||||
|
||||
if (LogAllMessages)
|
||||
{
|
||||
DeviceSession ds2 = this.Sessions.GetSession(e.DeviceId);
|
||||
OnMessage(new MessageIncomeResult(e.DeviceId, ds2, e));
|
||||
OnMessage(new MessageIncomeResult(e.DeviceId, ds, e));
|
||||
}
|
||||
|
||||
Client_TryAction(sender, e);
|
||||
@@ -303,10 +308,11 @@ namespace TelegramBotBase
|
||||
|
||||
private async void Client_TryAction(object sender, MessageResult e)
|
||||
{
|
||||
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
|
||||
DeviceSession ds = e.Device;
|
||||
if (ds == null)
|
||||
{
|
||||
ds = await this.Sessions.StartSession<T>(e.DeviceId);
|
||||
e.Device = ds;
|
||||
}
|
||||
|
||||
|
||||
@@ -322,11 +328,10 @@ namespace TelegramBotBase
|
||||
{
|
||||
i++;
|
||||
|
||||
activeForm = ds.ActiveForm;
|
||||
//Reset navigation
|
||||
ds.FormSwitched = false;
|
||||
|
||||
//If the form manages the events by itselfs, skip here
|
||||
if (activeForm.CustomEventManagement)
|
||||
return;
|
||||
activeForm = ds.ActiveForm;
|
||||
|
||||
//Pre Loading Event
|
||||
await activeForm.PreLoad(e);
|
||||
@@ -335,8 +340,12 @@ namespace TelegramBotBase
|
||||
await activeForm.Load(e);
|
||||
|
||||
//Action Event
|
||||
if (!activeForm.FormSwitched)
|
||||
if (!ds.FormSwitched)
|
||||
{
|
||||
//Send Action event to controls
|
||||
await activeForm.ActionControls(e);
|
||||
|
||||
//Send Action event to form itself
|
||||
await activeForm.Action(e);
|
||||
|
||||
if (!e.Handled)
|
||||
@@ -346,7 +355,7 @@ namespace TelegramBotBase
|
||||
|
||||
if (uhc.Handled)
|
||||
{
|
||||
if (activeForm.FormSwitched)
|
||||
if (ds.FormSwitched)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -360,10 +369,14 @@ namespace TelegramBotBase
|
||||
}
|
||||
|
||||
//Render Event
|
||||
if (!activeForm.FormSwitched)
|
||||
await activeForm.Render(e);
|
||||
if (!ds.FormSwitched)
|
||||
{
|
||||
await activeForm.RenderControls(e);
|
||||
|
||||
} while (activeForm.FormSwitched && i < NavigationMaximum);
|
||||
await activeForm.Render(e);
|
||||
}
|
||||
|
||||
} while (ds.FormSwitched && i < NavigationMaximum);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,277 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Enums;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
using static TelegramBotBase.Tools.Arrays;
|
||||
using static TelegramBotBase.Tools.Time;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
public class CalendarPicker : Base.ControlBase
|
||||
{
|
||||
|
||||
public DateTime SelectedDate { get; set; }
|
||||
|
||||
public DateTime VisibleMonth { get; set; }
|
||||
|
||||
public DayOfWeek FirstDayOfWeek { get; set; }
|
||||
|
||||
public CultureInfo Culture { get; set; }
|
||||
|
||||
|
||||
private int? MessageId { get; set; }
|
||||
|
||||
public String Title { get; set; } = "Pick Date";
|
||||
|
||||
public eMonthPickerMode PickerMode { get; set; }
|
||||
|
||||
public bool EnableDayView { get; set; } = true;
|
||||
|
||||
public bool EnableMonthView { get; set; } = true;
|
||||
|
||||
public bool EnableYearView { get; set; } = true;
|
||||
|
||||
public CalendarPicker()
|
||||
{
|
||||
this.SelectedDate = DateTime.Today;
|
||||
this.VisibleMonth = DateTime.Today;
|
||||
this.FirstDayOfWeek = DayOfWeek.Monday;
|
||||
this.Culture = new CultureInfo("de-de");
|
||||
this.PickerMode = eMonthPickerMode.day;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public override async Task Action(MessageResult result, String value = null)
|
||||
{
|
||||
await result.ConfirmAction();
|
||||
|
||||
switch (result.RawData)
|
||||
{
|
||||
case "next":
|
||||
|
||||
switch (this.PickerMode)
|
||||
{
|
||||
case eMonthPickerMode.day:
|
||||
this.VisibleMonth = this.VisibleMonth.AddMonths(1);
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.month:
|
||||
this.VisibleMonth = this.VisibleMonth.AddYears(1);
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.year:
|
||||
this.VisibleMonth = this.VisibleMonth.AddYears(10);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case "prev":
|
||||
|
||||
switch (this.PickerMode)
|
||||
{
|
||||
case eMonthPickerMode.day:
|
||||
this.VisibleMonth = this.VisibleMonth.AddMonths(-1);
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.month:
|
||||
this.VisibleMonth = this.VisibleMonth.AddYears(-1);
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.year:
|
||||
this.VisibleMonth = this.VisibleMonth.AddYears(-10);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "monthtitle":
|
||||
|
||||
if (this.EnableMonthView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.month;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "yeartitle":
|
||||
|
||||
if (this.EnableYearView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.year;
|
||||
}
|
||||
|
||||
break;
|
||||
case "yearstitle":
|
||||
|
||||
if (this.EnableMonthView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.month;
|
||||
}
|
||||
|
||||
this.VisibleMonth = this.SelectedDate;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
int day = 0;
|
||||
if (result.RawData.StartsWith("d-") && int.TryParse(result.RawData.Split('-')[1], out day))
|
||||
{
|
||||
this.SelectedDate = new DateTime(this.VisibleMonth.Year, this.VisibleMonth.Month, day);
|
||||
}
|
||||
|
||||
int month = 0;
|
||||
if (result.RawData.StartsWith("m-") && int.TryParse(result.RawData.Split('-')[1], out month))
|
||||
{
|
||||
this.SelectedDate = new DateTime(this.VisibleMonth.Year, month, 1);
|
||||
this.VisibleMonth = this.SelectedDate;
|
||||
|
||||
if (this.EnableDayView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.day;
|
||||
}
|
||||
}
|
||||
|
||||
int year = 0;
|
||||
if (result.RawData.StartsWith("y-") && int.TryParse(result.RawData.Split('-')[1], out year))
|
||||
{
|
||||
this.SelectedDate = new DateTime(year, SelectedDate.Month, SelectedDate.Day);
|
||||
this.VisibleMonth = this.SelectedDate;
|
||||
|
||||
if (this.EnableMonthView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.month;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override async Task Render(MessageResult result)
|
||||
{
|
||||
|
||||
|
||||
|
||||
ButtonForm bf = new ButtonForm();
|
||||
|
||||
switch (this.PickerMode)
|
||||
{
|
||||
case eMonthPickerMode.day:
|
||||
|
||||
var month = this.VisibleMonth;
|
||||
|
||||
string[] dayNamesNormal = this.Culture.DateTimeFormat.ShortestDayNames;
|
||||
string[] dayNamesShifted = Shift(dayNamesNormal, (int)this.FirstDayOfWeek);
|
||||
|
||||
bf.AddButtonRow(new ButtonBase("<<", "prev"), new ButtonBase(this.Culture.DateTimeFormat.MonthNames[month.Month - 1] + " " + month.Year.ToString(), "monthtitle"), new ButtonBase(">>", "next"));
|
||||
|
||||
bf.AddButtonRow(dayNamesShifted.Select(a => new ButtonBase(a, a)).ToList());
|
||||
|
||||
//First Day of month
|
||||
var firstDay = new DateTime(month.Year, month.Month, 1);
|
||||
|
||||
//Last Day of month
|
||||
var lastDay = firstDay.LastDayOfMonth();
|
||||
|
||||
//Start of Week where first day of month is (left border)
|
||||
var start = firstDay.StartOfWeek(this.FirstDayOfWeek);
|
||||
|
||||
//End of week where last day of month is (right border)
|
||||
var end = lastDay.EndOfWeek(this.FirstDayOfWeek);
|
||||
|
||||
for (int i = 0; i <= ((end - start).Days / 7); i++)
|
||||
{
|
||||
var lst = new List<ButtonBase>();
|
||||
for (int id = 0; id < 7; id++)
|
||||
{
|
||||
var d = start.AddDays((i * 7) + id);
|
||||
if (d < firstDay | d > lastDay)
|
||||
{
|
||||
lst.Add(new ButtonBase("-", "m-" + d.Day.ToString()));
|
||||
continue;
|
||||
}
|
||||
|
||||
var day = d.Day.ToString();
|
||||
|
||||
if (d == DateTime.Today)
|
||||
{
|
||||
day = "(" + day + ")";
|
||||
}
|
||||
|
||||
lst.Add(new ButtonBase((this.SelectedDate == d ? "[" + day + "]" : day), "d-" + d.Day.ToString()));
|
||||
}
|
||||
bf.AddButtonRow(lst);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.month:
|
||||
|
||||
bf.AddButtonRow(new ButtonBase("<<", "prev"), new ButtonBase(this.VisibleMonth.Year.ToString("0000"), "yeartitle"), new ButtonBase(">>", "next"));
|
||||
|
||||
var months = this.Culture.DateTimeFormat.MonthNames;
|
||||
|
||||
var buttons = months.Select((a, b) => new ButtonBase((b == this.SelectedDate.Month - 1 && this.SelectedDate.Year == this.VisibleMonth.Year ? "[ " + a + " ]" : a), "m-" + (b + 1).ToString()));
|
||||
|
||||
bf.AddSplitted(buttons, 2);
|
||||
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.year:
|
||||
|
||||
bf.AddButtonRow(new ButtonBase("<<", "prev"), new ButtonBase("Year", "yearstitle"), new ButtonBase(">>", "next"));
|
||||
|
||||
var starti = Math.Floor(this.VisibleMonth.Year / 10f) * 10;
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
var m = starti + (i * 2);
|
||||
bf.AddButtonRow(new ButtonBase((this.SelectedDate.Year == m ? "[ " + m.ToString() + " ]" : m.ToString()), "y-" + m.ToString()), new ButtonBase((this.SelectedDate.Year == (m + 1) ? "[ " + (m + 1).ToString() + " ]" : (m + 1).ToString()), "y-" + (m + 1).ToString()));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (this.MessageId != null)
|
||||
{
|
||||
var m = await this.Device.Edit(this.MessageId.Value, this.Title, bf);
|
||||
}
|
||||
else
|
||||
{
|
||||
var m = await this.Device.Send(this.Title, bf);
|
||||
this.MessageId = m.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override async Task Cleanup()
|
||||
{
|
||||
|
||||
if (this.MessageId != null)
|
||||
{
|
||||
await this.Device.DeleteMessage(this.MessageId.Value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Enums;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
public class MonthPicker : CalendarPicker
|
||||
{
|
||||
|
||||
|
||||
|
||||
public MonthPicker()
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.month;
|
||||
this.EnableDayView = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
@@ -220,7 +221,7 @@ namespace TelegramBotBase.Controls
|
||||
|
||||
}
|
||||
|
||||
public async override Task Render()
|
||||
public async override Task Render(MessageResult result)
|
||||
{
|
||||
if (!this.RenderNecessary)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
public class ToggleButton : ControlBase
|
||||
{
|
||||
|
||||
public String UncheckedIcon { get; set; } = "⚪";
|
||||
|
||||
public String CheckedIcon { get; set; } = "⚫";
|
||||
|
||||
public String CheckedString { get; set; } = "On";
|
||||
|
||||
public String UncheckedString { get; set; } = "Off";
|
||||
|
||||
public String Title { get; set; } = "Toggle";
|
||||
|
||||
public int? MessageId { get; set; }
|
||||
|
||||
public bool Checked { get; set; }
|
||||
|
||||
private bool RenderNecessary = true;
|
||||
|
||||
private static readonly object __evToggled = new object();
|
||||
|
||||
private readonly EventHandlerList Events = new EventHandlerList();
|
||||
|
||||
|
||||
public ToggleButton()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
public ToggleButton(String CheckedString, String UncheckedString)
|
||||
{
|
||||
this.CheckedString = CheckedString;
|
||||
this.UncheckedString = UncheckedString;
|
||||
}
|
||||
|
||||
public event EventHandler Toggled
|
||||
{
|
||||
add
|
||||
{
|
||||
this.Events.AddHandler(__evToggled, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
this.Events.RemoveHandler(__evToggled, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnToggled(EventArgs e)
|
||||
{
|
||||
(this.Events[__evToggled] as EventHandler)?.Invoke(this, e);
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult result, String value = null)
|
||||
{
|
||||
|
||||
if (result.Handled)
|
||||
return;
|
||||
|
||||
await result.ConfirmAction();
|
||||
|
||||
switch (value ?? "unknown")
|
||||
{
|
||||
case "on":
|
||||
|
||||
if (this.Checked)
|
||||
return;
|
||||
|
||||
RenderNecessary = true;
|
||||
|
||||
this.Checked = true;
|
||||
|
||||
OnToggled(new EventArgs());
|
||||
|
||||
break;
|
||||
|
||||
case "off":
|
||||
|
||||
if (!this.Checked)
|
||||
return;
|
||||
|
||||
RenderNecessary = true;
|
||||
|
||||
this.Checked = false;
|
||||
|
||||
OnToggled(new EventArgs());
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
RenderNecessary = false;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
result.Handled = true;
|
||||
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult result)
|
||||
{
|
||||
if (!RenderNecessary)
|
||||
return;
|
||||
|
||||
var bf = new ButtonForm(this);
|
||||
|
||||
ButtonBase bOn = new ButtonBase((this.Checked ? CheckedIcon : UncheckedIcon) + " " + CheckedString, "on");
|
||||
|
||||
ButtonBase bOff = new ButtonBase((!this.Checked ? CheckedIcon : UncheckedIcon) + " " + UncheckedString, "off");
|
||||
|
||||
bf.AddButtonRow(bOn, bOff);
|
||||
|
||||
if (this.MessageId != null)
|
||||
{
|
||||
var m = await this.Device.Edit(this.MessageId.Value, this.Title, bf);
|
||||
}
|
||||
else
|
||||
{
|
||||
var m = await this.Device.Send(this.Title, bf, disableNotification: true);
|
||||
if (m != null)
|
||||
{
|
||||
this.MessageId = m.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
this.RenderNecessary = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
public class TreeView : ControlBase
|
||||
{
|
||||
public List<TreeViewNode> Nodes { get; set; }
|
||||
|
||||
public TreeViewNode SelectedNode { get; set; }
|
||||
|
||||
public TreeViewNode VisibleNode { get; set; }
|
||||
|
||||
public String Title { get; set; }
|
||||
|
||||
private int? MessageId { get; set; }
|
||||
|
||||
public String MoveUpIcon { get; set; } = "🔼 up";
|
||||
|
||||
public TreeView()
|
||||
{
|
||||
this.Nodes = new List<TreeViewNode>();
|
||||
this.Title = "Select node";
|
||||
}
|
||||
|
||||
|
||||
public override async Task Action(MessageResult result, String value = null)
|
||||
{
|
||||
await result.ConfirmAction();
|
||||
|
||||
if (result.Handled)
|
||||
return;
|
||||
|
||||
var val = result.RawData;
|
||||
|
||||
switch (val)
|
||||
{
|
||||
case "up":
|
||||
case "parent":
|
||||
|
||||
this.VisibleNode = (this.VisibleNode?.ParentNode);
|
||||
|
||||
result.Handled = true;
|
||||
|
||||
break;
|
||||
default:
|
||||
|
||||
var n = (this.VisibleNode != null ? this.VisibleNode.FindNodeByValue(val) : this.Nodes.FirstOrDefault(a => a.Value == val));
|
||||
|
||||
if (n != null)
|
||||
{
|
||||
if (n.ChildNodes.Count > 0)
|
||||
{
|
||||
this.VisibleNode = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.SelectedNode = (this.SelectedNode != n ? n : null);
|
||||
}
|
||||
|
||||
result.Handled = true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override async Task Render(MessageResult result)
|
||||
{
|
||||
var startnode = this.VisibleNode;
|
||||
|
||||
var nodes = (startnode?.ChildNodes ?? this.Nodes);
|
||||
|
||||
ButtonForm bf = new ButtonForm();
|
||||
|
||||
if (startnode != null)
|
||||
{
|
||||
bf.AddButtonRow(new ButtonBase(this.MoveUpIcon, "up"), new ButtonBase(startnode.Text, "parent"));
|
||||
}
|
||||
|
||||
foreach (var n in nodes)
|
||||
{
|
||||
var s = n.Text;
|
||||
if (this.SelectedNode == n)
|
||||
{
|
||||
s = "[ " + s + " ]";
|
||||
}
|
||||
|
||||
bf.AddButtonRow(new ButtonBase(s, n.Value, n.Url));
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (this.MessageId != null)
|
||||
{
|
||||
var m = await this.Device.Edit(this.MessageId.Value, this.Title, bf);
|
||||
}
|
||||
else
|
||||
{
|
||||
var m = await this.Device.Send(this.Title, bf);
|
||||
this.MessageId = m.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
public String GetPath()
|
||||
{
|
||||
return (this.VisibleNode?.GetPath() ?? "\\");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
public class TreeViewNode
|
||||
{
|
||||
public String Text { get; set; }
|
||||
|
||||
public String Value { get; set; }
|
||||
|
||||
public String Url { get; set; }
|
||||
|
||||
public List<TreeViewNode> ChildNodes { get; set; } = new List<TreeViewNode>();
|
||||
|
||||
public TreeViewNode ParentNode { get; set; }
|
||||
|
||||
public TreeViewNode(String Text, String Value)
|
||||
{
|
||||
this.Text = Text;
|
||||
this.Value = Value;
|
||||
}
|
||||
|
||||
public TreeViewNode(String Text, String Value, String Url) : this(Text, Value)
|
||||
{
|
||||
this.Url = Url;
|
||||
}
|
||||
|
||||
public TreeViewNode(String Text, String Value, params TreeViewNode[] childnodes) : this(Text, Value)
|
||||
{
|
||||
foreach(var c in childnodes)
|
||||
{
|
||||
AddNode(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void AddNode(TreeViewNode node)
|
||||
{
|
||||
node.ParentNode = this;
|
||||
ChildNodes.Add(node);
|
||||
}
|
||||
|
||||
public TreeViewNode FindNodeByValue(String Value)
|
||||
{
|
||||
return this.ChildNodes.FirstOrDefault(a => a.Value == Value);
|
||||
}
|
||||
|
||||
public String GetPath()
|
||||
{
|
||||
String s = "\\" + this.Value;
|
||||
var p = this;
|
||||
while (p.ParentNode != null)
|
||||
{
|
||||
s = "\\" + p.ParentNode.Value + s;
|
||||
p = p.ParentNode;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Enums
|
||||
{
|
||||
public enum eDeleteMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Don't delete any message.
|
||||
/// </summary>
|
||||
None = 0,
|
||||
/// <summary>
|
||||
/// Delete messages on every callback/action.
|
||||
/// </summary>
|
||||
OnEveryCall = 1,
|
||||
/// <summary>
|
||||
/// Delete on leaving this form.
|
||||
/// </summary>
|
||||
OnLeavingForm = 2
|
||||
}
|
||||
|
||||
public enum eSide
|
||||
{
|
||||
/// <summary>
|
||||
/// Delete only messages from this bot.
|
||||
/// </summary>
|
||||
BotOnly = 0,
|
||||
/// <summary>
|
||||
/// Delete only user messages.
|
||||
/// </summary>
|
||||
UserOnly = 1,
|
||||
/// <summary>
|
||||
/// Delete all messages in this context.
|
||||
/// </summary>
|
||||
Both = 2
|
||||
}
|
||||
|
||||
public enum eMonthPickerMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Shows the calendar with day picker mode
|
||||
/// </summary>
|
||||
day = 0,
|
||||
/// <summary>
|
||||
/// Shows the calendar with month overview
|
||||
/// </summary>
|
||||
month = 1,
|
||||
/// <summary>
|
||||
/// Shows the calendar with year overview
|
||||
/// </summary>
|
||||
year = 2
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Enums;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
{
|
||||
@@ -17,30 +18,47 @@ namespace TelegramBotBase.Form
|
||||
|
||||
public eDeleteMode DeleteMode { get; set; }
|
||||
|
||||
public enum eDeleteMode
|
||||
{
|
||||
None = 0,
|
||||
OnEveryCall = 1,
|
||||
OnLeavingForm = 2
|
||||
}
|
||||
public eSide DeleteSide { get; set; }
|
||||
|
||||
|
||||
|
||||
public AutoCleanForm()
|
||||
{
|
||||
this.OldMessages = new List<Message>();
|
||||
this.DeleteMode = eDeleteMode.OnEveryCall;
|
||||
this.DeleteSide = eSide.BotOnly;
|
||||
|
||||
this.Init += AutoCleanForm_Init;
|
||||
|
||||
this.Closed += AutoCleanForm_Closed;
|
||||
|
||||
}
|
||||
|
||||
public override async Task Init(params object[] args)
|
||||
|
||||
private async Task AutoCleanForm_Init(object sender, InitEventArgs e)
|
||||
{
|
||||
if (this.Device == null)
|
||||
return;
|
||||
|
||||
this.Device.MessageSent += Device_MessageSent;
|
||||
|
||||
this.Device.MessageReceived += Device_MessageReceived;
|
||||
}
|
||||
|
||||
|
||||
private void Device_MessageReceived(object sender, MessageReceivedEventArgs e)
|
||||
{
|
||||
if (this.DeleteSide == eSide.BotOnly)
|
||||
return;
|
||||
|
||||
this.OldMessages.Add(e.Message);
|
||||
}
|
||||
|
||||
private void Device_MessageSent(object sender, MessageSentEventArgs e)
|
||||
{
|
||||
if (this.DeleteSide == eSide.UserOnly)
|
||||
return;
|
||||
|
||||
this.OldMessages.Add(e.Message);
|
||||
}
|
||||
|
||||
@@ -49,19 +67,11 @@ namespace TelegramBotBase.Form
|
||||
if (this.DeleteMode != eDeleteMode.OnEveryCall)
|
||||
return;
|
||||
|
||||
while (this.OldMessages.Count > 0)
|
||||
{
|
||||
if (!await this.Device.DeleteMessage(this.OldMessages[0].MessageId))
|
||||
{
|
||||
//Nachricht konnte nicht gelöscht werden, vermutlich existiert diese nicht mehr
|
||||
if (this.OldMessages.Count > 0)
|
||||
this.OldMessages.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
await MessageCleanup();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fügt eine Nachricht zu der Liste der löschenden hinzu.
|
||||
/// Adds a message to this of removable ones
|
||||
/// </summary>
|
||||
/// <param name="Id"></param>
|
||||
public void AddMessage(Message m)
|
||||
@@ -70,7 +80,7 @@ namespace TelegramBotBase.Form
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Behält die Nachricht mit der angegebenen Id.
|
||||
/// Keeps the message by removing it from the list
|
||||
/// </summary>
|
||||
/// <param name="Id"></param>
|
||||
public void LeaveMessage(int Id)
|
||||
@@ -83,7 +93,7 @@ namespace TelegramBotBase.Form
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Behält die zuletzt gesendete Nachricht.
|
||||
/// Keeps the last sent message
|
||||
/// </summary>
|
||||
public void LeaveLastMessage()
|
||||
{
|
||||
@@ -93,14 +103,28 @@ namespace TelegramBotBase.Form
|
||||
this.OldMessages.RemoveAt(this.OldMessages.Count - 1);
|
||||
}
|
||||
|
||||
public async override Task Closed()
|
||||
private async Task AutoCleanForm_Closed(object sender, EventArgs e)
|
||||
{
|
||||
if (this.DeleteMode != eDeleteMode.OnLeavingForm)
|
||||
return;
|
||||
|
||||
foreach (var m in this.OldMessages)
|
||||
await MessageCleanup();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleans up all remembered messages.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task MessageCleanup()
|
||||
{
|
||||
while (this.OldMessages.Count > 0)
|
||||
{
|
||||
await this.Device.DeleteMessage(m.MessageId);
|
||||
if (!await this.Device.DeleteMessage(this.OldMessages[0].MessageId))
|
||||
{
|
||||
//Message can't be deleted cause it seems not to exist anymore
|
||||
if (this.OldMessages.Count > 0)
|
||||
this.OldMessages.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types.ReplyMarkups;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
{
|
||||
@@ -15,15 +16,36 @@ namespace TelegramBotBase.Form
|
||||
|
||||
public String Value { get; set; }
|
||||
|
||||
public String Url { get; set; }
|
||||
|
||||
public ButtonBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ButtonBase(String Text, String Value)
|
||||
public ButtonBase(String Text, String Value, String Url = null)
|
||||
{
|
||||
this.Text = Text;
|
||||
this.Value = Value;
|
||||
this.Url = Url;
|
||||
}
|
||||
|
||||
|
||||
public InlineKeyboardButton ToInlineButton(ButtonForm form)
|
||||
{
|
||||
String id = (form.DependencyControl != null ? form.DependencyControl.ControlID + "_" : "");
|
||||
if (this.Url == null)
|
||||
{
|
||||
return InlineKeyboardButton.WithCallbackData(this.Text, id + this.Value);
|
||||
}
|
||||
|
||||
var ikb = new InlineKeyboardButton();
|
||||
|
||||
ikb.Text = this.Text;
|
||||
ikb.Url = this.Url;
|
||||
|
||||
return ikb;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types.ReplyMarkups;
|
||||
using TelegramBotBase.Base;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
{
|
||||
@@ -14,14 +15,24 @@ namespace TelegramBotBase.Form
|
||||
{
|
||||
List<List<ButtonBase>> Buttons = new List<List<ButtonBase>>();
|
||||
|
||||
|
||||
public IReplyMarkup Markup { get; set; }
|
||||
|
||||
public ControlBase DependencyControl { get; set; }
|
||||
|
||||
public ButtonForm()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void AddButtonRow(List<ButtonBase> row)
|
||||
public ButtonForm(ControlBase control)
|
||||
{
|
||||
Buttons.Add(row);
|
||||
this.DependencyControl = control;
|
||||
}
|
||||
|
||||
public void AddButtonRow(IEnumerable<ButtonBase> row)
|
||||
{
|
||||
Buttons.Add(row.ToList());
|
||||
}
|
||||
|
||||
public void AddButtonRow(params ButtonBase[] row)
|
||||
@@ -58,7 +69,7 @@ namespace TelegramBotBase.Form
|
||||
{
|
||||
var sp = SplitTo<ButtonBase>(buttons, buttonsPerRow);
|
||||
|
||||
foreach(var bl in sp)
|
||||
foreach (var bl in sp)
|
||||
{
|
||||
AddButtonRow(bl);
|
||||
}
|
||||
@@ -66,13 +77,16 @@ namespace TelegramBotBase.Form
|
||||
|
||||
public InlineKeyboardButton[][] ToArray()
|
||||
{
|
||||
var ikb = this.Buttons.Select(a => a.Select(b => InlineKeyboardButton.WithCallbackData(b.Text, b.Value)).ToArray()).ToArray();
|
||||
var ikb = this.Buttons.Select(a => a.Select(b => b.ToInlineButton(this)).ToArray()).ToArray();
|
||||
|
||||
return ikb;
|
||||
}
|
||||
|
||||
public static implicit operator InlineKeyboardMarkup(ButtonForm form)
|
||||
{
|
||||
if (form == null)
|
||||
return null;
|
||||
|
||||
InlineKeyboardMarkup ikm = new InlineKeyboardMarkup(form.ToArray());
|
||||
|
||||
return ikm;
|
||||
|
||||
@@ -6,7 +6,7 @@ using System.Runtime.InteropServices;
|
||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||
// die einer Assembly zugeordnet sind.
|
||||
[assembly: AssemblyTitle("TelegramBotBase Framework")]
|
||||
[assembly: AssemblyDescription("A simple addon for the original C# Telegram Bot library.")]
|
||||
[assembly: AssemblyDescription("This is a context based application framework for the C# TelegramBot library.")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Florian Dahn")]
|
||||
[assembly: AssemblyProduct("TelegramBotBase Framework")]
|
||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
|
||||
// übernehmen, indem Sie "*" eingeben:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.4.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.4.0.0")]
|
||||
[assembly: AssemblyVersion("1.5.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.5.0.0")]
|
||||
|
||||
@@ -67,9 +67,9 @@ namespace TelegramBotBase
|
||||
DeviceSession ds = new Sessions.DeviceSession(deviceId, start);
|
||||
|
||||
start.Device = ds;
|
||||
await start.Init();
|
||||
await start.OnInit(new InitEventArgs());
|
||||
|
||||
await start.Opened();
|
||||
await start.OnOpened(new EventArgs());
|
||||
|
||||
this[deviceId] = ds;
|
||||
return ds;
|
||||
|
||||
@@ -37,6 +37,16 @@ namespace TelegramBotBase.Sessions
|
||||
/// </summary>
|
||||
public FormBase ActiveForm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the previous shown form
|
||||
/// </summary>
|
||||
public FormBase PreviousForm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// contains if the form has been switched (navigated)
|
||||
/// </summary>
|
||||
public bool FormSwitched { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the ID of the last received message.
|
||||
/// </summary>
|
||||
@@ -68,13 +78,25 @@ namespace TelegramBotBase.Sessions
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.LastMessage != null && this.LastMessage.Chat.Id != this.LastMessage.From.Id;
|
||||
return this.LastMessage != null && (this.LastMessage.Chat.Type == ChatType.Group | this.LastMessage.Chat.Type == ChatType.Supergroup);
|
||||
}
|
||||
}
|
||||
|
||||
public EventHandlerList __Events = new EventHandlerList();
|
||||
/// <summary>
|
||||
/// Returns if the messages is posted within a channel.
|
||||
/// </summary>
|
||||
public bool IsChannel
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.LastMessage != null && this.LastMessage.Chat.Type == ChatType.Channel;
|
||||
}
|
||||
}
|
||||
|
||||
private EventHandlerList __Events = new EventHandlerList();
|
||||
|
||||
private static object __evMessageSent = new object();
|
||||
private static object __evMessageReceived = new object();
|
||||
|
||||
public DeviceSession()
|
||||
{
|
||||
@@ -105,11 +127,7 @@ namespace TelegramBotBase.Sessions
|
||||
if (this.ActiveForm == null)
|
||||
return null;
|
||||
|
||||
InlineKeyboardMarkup markup = null;
|
||||
if (buttons != null)
|
||||
{
|
||||
markup = buttons;
|
||||
}
|
||||
InlineKeyboardMarkup markup = buttons;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -126,6 +144,35 @@ namespace TelegramBotBase.Sessions
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Edits the text message
|
||||
/// </summary>
|
||||
/// <param name="messageId"></param>
|
||||
/// <param name="text"></param>
|
||||
/// <param name="buttons"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> Edit(Message message, ButtonForm buttons = null)
|
||||
{
|
||||
if (this.ActiveForm == null)
|
||||
return null;
|
||||
|
||||
InlineKeyboardMarkup markup = buttons;
|
||||
|
||||
try
|
||||
{
|
||||
var m = await this.Client.TelegramClient.EditMessageTextAsync(this.DeviceId, message.MessageId, message.Text, replyMarkup: markup);
|
||||
|
||||
return m;
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a simple text message
|
||||
/// </summary>
|
||||
@@ -139,11 +186,7 @@ namespace TelegramBotBase.Sessions
|
||||
if (this.ActiveForm == null)
|
||||
return null;
|
||||
|
||||
InlineKeyboardMarkup markup = null;
|
||||
if (buttons != null)
|
||||
{
|
||||
markup = buttons;
|
||||
}
|
||||
InlineKeyboardMarkup markup = buttons;
|
||||
|
||||
Message m = null;
|
||||
|
||||
@@ -151,7 +194,7 @@ namespace TelegramBotBase.Sessions
|
||||
{
|
||||
m = await (this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, text, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m.MessageId, m));
|
||||
OnMessageSent(new MessageSentEventArgs(m));
|
||||
}
|
||||
catch (ApiRequestException ex)
|
||||
{
|
||||
@@ -184,7 +227,40 @@ namespace TelegramBotBase.Sessions
|
||||
{
|
||||
m = await (this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, text, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m.MessageId, m));
|
||||
OnMessageSent(new MessageSentEventArgs(m));
|
||||
}
|
||||
catch (ApiRequestException ex)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a simple text message
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <param name="markup"></param>
|
||||
/// <param name="replyTo"></param>
|
||||
/// <param name="disableNotification"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> Send(String text, ReplyKeyboardMarkup markup, int replyTo = 0, bool disableNotification = false)
|
||||
{
|
||||
if (this.ActiveForm == null)
|
||||
return null;
|
||||
|
||||
Message m = null;
|
||||
|
||||
try
|
||||
{
|
||||
m = await (this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, text, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m));
|
||||
}
|
||||
catch (ApiRequestException ex)
|
||||
{
|
||||
@@ -211,11 +287,7 @@ namespace TelegramBotBase.Sessions
|
||||
if (this.ActiveForm == null)
|
||||
return null;
|
||||
|
||||
InlineKeyboardMarkup markup = null;
|
||||
if (buttons != null)
|
||||
{
|
||||
markup = buttons;
|
||||
}
|
||||
InlineKeyboardMarkup markup = buttons;
|
||||
|
||||
Message m = null;
|
||||
|
||||
@@ -223,7 +295,7 @@ namespace TelegramBotBase.Sessions
|
||||
{
|
||||
m = await this.Client.TelegramClient.SendPhotoAsync(this.DeviceId, file, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification);
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m.MessageId, m));
|
||||
OnMessageSent(new MessageSentEventArgs(m));
|
||||
}
|
||||
catch (ApiRequestException ex)
|
||||
{
|
||||
@@ -318,8 +390,8 @@ namespace TelegramBotBase.Sessions
|
||||
}
|
||||
|
||||
var m = await this.Client.TelegramClient.SendDocumentAsync(this.DeviceId, document, caption, replyMarkup: markup, disableNotification: disableNotification, replyToMessageId: replyTo);
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m.MessageId, m));
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m));
|
||||
|
||||
return m;
|
||||
}
|
||||
@@ -414,5 +486,25 @@ namespace TelegramBotBase.Sessions
|
||||
(this.__Events[__evMessageSent] as EventHandler<MessageSentEventArgs>)?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Eventhandler for received messages
|
||||
/// </summary>
|
||||
public event EventHandler<MessageReceivedEventArgs> MessageReceived
|
||||
{
|
||||
add
|
||||
{
|
||||
this.__Events.AddHandler(__evMessageReceived, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
this.__Events.RemoveHandler(__evMessageReceived, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void OnMessageReceived(MessageReceivedEventArgs e)
|
||||
{
|
||||
(this.__Events[__evMessageReceived] as EventHandler<MessageReceivedEventArgs>)?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBase.Tools
|
||||
{
|
||||
public static class Arrays
|
||||
{
|
||||
public static T[] Shift<T>(T[] array, int positions)
|
||||
{
|
||||
T[] copy = new T[array.Length];
|
||||
Array.Copy(array, 0, copy, array.Length - positions, positions);
|
||||
Array.Copy(array, positions, copy, 0, array.Length - positions);
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Tools
|
||||
{
|
||||
public static class Time
|
||||
{
|
||||
public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
|
||||
{
|
||||
int diff = dt.DayOfWeek - startOfWeek;
|
||||
if (diff < 0)
|
||||
{
|
||||
diff += 7;
|
||||
}
|
||||
return dt.AddDays(-1 * diff).Date;
|
||||
}
|
||||
|
||||
public static DateTime EndOfWeek(this DateTime dt, DayOfWeek startOfWeek)
|
||||
{
|
||||
return StartOfWeek(dt, startOfWeek).AddDays(6);
|
||||
}
|
||||
|
||||
public static DateTime FirstDayOfMonth(this DateTime date)
|
||||
{
|
||||
return new DateTime(date.Year, date.Month, 1);
|
||||
}
|
||||
|
||||
public static DateTime LastDayOfMonth(this DateTime date)
|
||||
{
|
||||
return FirstDayOfMonth(date).AddMonths(1).AddDays(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 307 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
|
After Width: | Height: | Size: 185 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 5.7 KiB |