Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a309baeae | ||
|
|
e02af0fc76 | ||
|
|
530e01f971 | ||
|
|
dcf3cf804f | ||
|
|
a42d3934b5 | ||
|
|
2126b45fed | ||
|
|
b6b9d5b6b1 | ||
|
|
eed5f012dc | ||
|
|
de4cc138ae | ||
|
|
e4da70d37d | ||
|
|
cb4a797b12 |
@@ -1,4 +1,5 @@
|
|||||||
|
|
||||||
|
|
||||||
# .Net Telegram Bot Framework - Context based addon
|
# .Net Telegram Bot Framework - Context based addon
|
||||||
|
|
||||||
[](https://www.nuget.org/packages/TelegramBotBase/)
|
[](https://www.nuget.org/packages/TelegramBotBase/)
|
||||||
@@ -38,6 +39,14 @@ Download a release: [Releases](https://github.com/MajMcCloud/TelegramBotFramewor
|
|||||||
|
|
||||||
* [PromptDialog](#prompt-dialog)
|
* [PromptDialog](#prompt-dialog)
|
||||||
|
|
||||||
|
- [Controls](#controls)
|
||||||
|
* [ProgressBar](#progress-bar)
|
||||||
|
|
||||||
|
* [CalendarPicker](#calendar-picker)
|
||||||
|
|
||||||
|
* [MonthPicker](#month-picker)
|
||||||
|
|
||||||
|
+ [TreeView](#tree-view)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -221,7 +230,7 @@ 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)
|
### Lets start with text messages (Example #1 - Simple Test)
|
||||||
|
|
||||||
|
<img src="images/example1.PNG" />
|
||||||
|
|
||||||
```
|
```
|
||||||
public class SimpleForm : AutoCleanForm
|
public class SimpleForm : AutoCleanForm
|
||||||
@@ -276,6 +285,7 @@ public class SimpleForm : AutoCleanForm
|
|||||||
|
|
||||||
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.
|
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
|
public class ButtonTestForm : AutoCleanForm
|
||||||
@@ -353,6 +363,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("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()));
|
btn.AddButtonRow(new ButtonBase("Back", new CallbackData("a", "back").Serialize()));
|
||||||
|
|
||||||
await this.Device.Send("Click a button", btn);
|
await this.Device.Send("Click a button", btn);
|
||||||
@@ -368,6 +380,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.
|
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.
|
Maybe, if i got more ideas, i will add other "controls" in the future.
|
||||||
|
|
||||||
|
<img src="images/example3.PNG" />
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
public class ProgressTest : AutoCleanForm
|
public class ProgressTest : AutoCleanForm
|
||||||
@@ -502,6 +516,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.
|
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.
|
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
|
public class PerForm : AutoCleanForm
|
||||||
@@ -624,6 +646,8 @@ For now we have the following:
|
|||||||
|
|
||||||
### Alert Dialog
|
### Alert Dialog
|
||||||
|
|
||||||
|
<img src="images/alertdialog.PNG" />
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
var fto = new TestForm2();
|
var fto = new TestForm2();
|
||||||
@@ -637,10 +661,12 @@ await this.NavigateTo(ad);
|
|||||||
|
|
||||||
### AutoCleanForm
|
### AutoCleanForm
|
||||||
|
|
||||||
|
No example yet
|
||||||
|
|
||||||
### Prompt Dialog
|
### Prompt Dialog
|
||||||
|
|
||||||
|
<img src="images/promptdialog.PNG" />
|
||||||
|
|
||||||
#### Without Eventhandler (pre-init of form necessary)
|
#### Without Eventhandler (pre-init of form necessary)
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -678,6 +704,30 @@ await this.NavigateTo(pd);
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Controls
|
||||||
|
|
||||||
|
### Progress Bar
|
||||||
|
<img src="images/progressbar.PNG?raw=true" />
|
||||||
|
|
||||||
|
|
||||||
|
### Calendar Picker
|
||||||
|
<img src="images/calendarpicker.PNG?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" />
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
I will add more notes to it soon, so stay tuned.
|
I will add more notes to it soon, so stay tuned.
|
||||||
|
|||||||
@@ -11,7 +11,12 @@ namespace TelegramBaseTest.Tests
|
|||||||
public class ButtonTestForm : AutoCleanForm
|
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)");
|
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("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()));
|
btn.AddButtonRow(new ButtonBase("Back", new CallbackData("a", "back").Serialize()));
|
||||||
|
|
||||||
await this.Device.Send("Click a button", btn);
|
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,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()
|
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");
|
await this.Device.Send("Welcome to ProgressTest");
|
||||||
}
|
}
|
||||||
@@ -87,14 +90,14 @@ namespace TelegramBaseTest.Tests
|
|||||||
|
|
||||||
|
|
||||||
//Render Progress bar and show some "example" progress
|
//Render Progress bar and show some "example" progress
|
||||||
await Bar.Render();
|
await Bar.Render(message);
|
||||||
|
|
||||||
this.Controls.Add(Bar);
|
this.Controls.Add(Bar);
|
||||||
|
|
||||||
for (int i = 0; i <= 100; i++)
|
for (int i = 0; i <= 100; i++)
|
||||||
{
|
{
|
||||||
Bar.Value++;
|
Bar.Value++;
|
||||||
await Bar.Render();
|
await Bar.Render(message);
|
||||||
|
|
||||||
Thread.Sleep(250);
|
Thread.Sleep(250);
|
||||||
}
|
}
|
||||||
@@ -117,17 +120,10 @@ namespace TelegramBaseTest.Tests
|
|||||||
await this.Device.Send("Choose your progress bar:", btn);
|
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");
|
await this.Device.Send("Ciao from ProgressTest");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,11 +12,17 @@ namespace TelegramBaseTest.Tests.Register.Steps
|
|||||||
{
|
{
|
||||||
public Data UserData { get; set; }
|
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();
|
this.UserData = new Data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async override Task Load(MessageResult message)
|
public async override Task Load(MessageResult message)
|
||||||
{
|
{
|
||||||
if (message.Handled)
|
if (message.Handled)
|
||||||
|
|||||||
@@ -13,16 +13,17 @@ namespace TelegramBaseTest.Tests
|
|||||||
|
|
||||||
public SimpleForm()
|
public SimpleForm()
|
||||||
{
|
{
|
||||||
this.DeleteSide = eSide.Both;
|
this.DeleteSide = TelegramBotBase.Enums.eSide.Both;
|
||||||
this.DeleteMode = eDeleteMode.OnLeavingForm;
|
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
|
||||||
|
|
||||||
|
this.Opened += SimpleForm_Opened;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task 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");
|
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)
|
public override async Task Load(MessageResult message)
|
||||||
{
|
{
|
||||||
//message.MessageText will work also, cause it is a string you could manage a lot different scenerios here
|
//message.MessageText will work also, cause it is a string you could manage a lot different scenerios here
|
||||||
|
|||||||
@@ -8,8 +8,12 @@ using TelegramBotBase.Form;
|
|||||||
|
|
||||||
namespace TelegramBaseTest.Tests
|
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)
|
public override async Task Action(MessageResult message)
|
||||||
{
|
{
|
||||||
@@ -79,6 +83,36 @@ namespace TelegramBaseTest.Tests
|
|||||||
|
|
||||||
await this.NavigateTo(data);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,6 +133,10 @@ namespace TelegramBaseTest.Tests
|
|||||||
btn.AddButtonRow(new ButtonBase("#6 Form2 Command", new CallbackData("a", "form2").Serialize()));
|
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("#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()));
|
||||||
|
|
||||||
await this.Device.Send("Choose your test:", btn);
|
await this.Device.Send("Choose your test:", btn);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,13 +15,18 @@ namespace TelegramBaseTest.Tests
|
|||||||
|
|
||||||
String LastMessage { get; set; }
|
String LastMessage { get; set; }
|
||||||
|
|
||||||
|
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");
|
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");
|
await this.Device.Send("Ciao from Form 1");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,17 +16,25 @@ namespace TelegramBaseTest.Tests
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
public override async Task Opened()
|
public TestForm2()
|
||||||
|
{
|
||||||
|
this.Opened += TestForm2_Opened;
|
||||||
|
this.Closed += TestForm2_Closed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task TestForm2_Opened(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
await this.Device.Send("Welcome to Form 2");
|
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");
|
await this.Device.Send("Ciao from Form 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public override async Task Action(MessageResult message)
|
public override async Task Action(MessageResult message)
|
||||||
{
|
{
|
||||||
var call = message.GetData<CallbackData>();
|
var call = message.GetData<CallbackData>();
|
||||||
|
|||||||
@@ -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,9 +13,26 @@ namespace TelegramBotBase.Base
|
|||||||
{
|
{
|
||||||
public Sessions.DeviceSession Device { get; set; }
|
public Sessions.DeviceSession Device { get; set; }
|
||||||
|
|
||||||
public virtual async Task Render()
|
public int ID { get; set; }
|
||||||
|
|
||||||
|
/// <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)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task Render(MessageResult result)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task Cleanup()
|
public virtual async Task Cleanup()
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using TelegramBotBase.Base;
|
using TelegramBotBase.Base;
|
||||||
using TelegramBotBase.Sessions;
|
using TelegramBotBase.Sessions;
|
||||||
|
using static TelegramBotBase.Base.Async;
|
||||||
|
|
||||||
namespace TelegramBotBase.Form
|
namespace TelegramBotBase.Form
|
||||||
{
|
{
|
||||||
@@ -13,12 +15,11 @@ namespace TelegramBotBase.Form
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class FormBase : IDisposable
|
public class FormBase : IDisposable
|
||||||
{
|
{
|
||||||
|
|
||||||
public DeviceSession Device { get; set; }
|
public DeviceSession Device { get; set; }
|
||||||
|
|
||||||
public MessageClient Client { get; set; }
|
public MessageClient Client { get; set; }
|
||||||
|
|
||||||
public bool CustomEventManagement { get; set; } = false;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// has this formular already been disposed ?
|
/// has this formular already been disposed ?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -26,34 +27,119 @@ namespace TelegramBotBase.Form
|
|||||||
|
|
||||||
public List<ControlBase> Controls { get; set; }
|
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()
|
public FormBase()
|
||||||
{
|
{
|
||||||
this.Controls = new List<Base.ControlBase>();
|
this.Controls = new List<Base.ControlBase>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FormBase(MessageClient Client): this()
|
public FormBase(MessageClient Client) : this()
|
||||||
{
|
{
|
||||||
this.Client = Client;
|
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>
|
/// <summary>
|
||||||
/// Gets invoked if gets navigated to this form
|
/// Gets invoked if gets navigated to this form
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <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)
|
foreach (var b in this.Controls)
|
||||||
{
|
{
|
||||||
@@ -76,6 +162,22 @@ 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)
|
||||||
|
{
|
||||||
|
foreach (var b in this.Controls)
|
||||||
|
{
|
||||||
|
if (!b.Enabled)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
await b.Action(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets invoked if the user has clicked a button.
|
/// Gets invoked if the user has clicked a button.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -96,6 +198,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>
|
/// <summary>
|
||||||
/// Gets invoked at the end of the cycle to "Render" text, images, buttons, etc...
|
/// Gets invoked at the end of the cycle to "Render" text, images, buttons, etc...
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -106,6 +224,8 @@ namespace TelegramBotBase.Form
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Navigates to a new form
|
/// Navigates to a new form
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -125,11 +245,20 @@ namespace TelegramBotBase.Form
|
|||||||
newForm.Client = this.Client;
|
newForm.Client = this.Client;
|
||||||
newForm.Device = ds;
|
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>
|
/// <summary>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -264,10 +264,6 @@ namespace TelegramBotBase
|
|||||||
|
|
||||||
activeForm = ds.ActiveForm;
|
activeForm = ds.ActiveForm;
|
||||||
|
|
||||||
//If the form manages the events by itselfs, skip here
|
|
||||||
if (activeForm.CustomEventManagement)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//Pre Loading Event
|
//Pre Loading Event
|
||||||
await activeForm.PreLoad(e);
|
await activeForm.PreLoad(e);
|
||||||
|
|
||||||
@@ -337,10 +333,6 @@ namespace TelegramBotBase
|
|||||||
|
|
||||||
activeForm = ds.ActiveForm;
|
activeForm = ds.ActiveForm;
|
||||||
|
|
||||||
//If the form manages the events by itselfs, skip here
|
|
||||||
if (activeForm.CustomEventManagement)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//Pre Loading Event
|
//Pre Loading Event
|
||||||
await activeForm.PreLoad(e);
|
await activeForm.PreLoad(e);
|
||||||
|
|
||||||
@@ -350,6 +342,10 @@ namespace TelegramBotBase
|
|||||||
//Action Event
|
//Action Event
|
||||||
if (!ds.FormSwitched)
|
if (!ds.FormSwitched)
|
||||||
{
|
{
|
||||||
|
//Send Action event to controls
|
||||||
|
await activeForm.ActionControls(e);
|
||||||
|
|
||||||
|
//Send Action event to form itself
|
||||||
await activeForm.Action(e);
|
await activeForm.Action(e);
|
||||||
|
|
||||||
if (!e.Handled)
|
if (!e.Handled)
|
||||||
@@ -374,7 +370,11 @@ namespace TelegramBotBase
|
|||||||
|
|
||||||
//Render Event
|
//Render Event
|
||||||
if (!ds.FormSwitched)
|
if (!ds.FormSwitched)
|
||||||
|
{
|
||||||
|
await activeForm.RenderControls(e);
|
||||||
|
|
||||||
await activeForm.Render(e);
|
await activeForm.Render(e);
|
||||||
|
}
|
||||||
|
|
||||||
} while (ds.FormSwitched && i < NavigationMaximum);
|
} 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)
|
||||||
|
{
|
||||||
|
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.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using TelegramBotBase.Base;
|
||||||
|
|
||||||
namespace TelegramBotBase.Controls
|
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)
|
if (!this.RenderNecessary)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
|
{
|
||||||
|
await result.ConfirmAction();
|
||||||
|
|
||||||
|
if (result.Handled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var value = result.RawData;
|
||||||
|
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case "up":
|
||||||
|
case "parent":
|
||||||
|
|
||||||
|
this.VisibleNode = (this.VisibleNode?.ParentNode);
|
||||||
|
|
||||||
|
result.Handled = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
var n = (this.VisibleNode != null ? this.VisibleNode.FindNodeByValue(value) : this.Nodes.FirstOrDefault(a => a.Value == value));
|
||||||
|
|
||||||
|
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 System.Threading.Tasks;
|
||||||
using Telegram.Bot.Types;
|
using Telegram.Bot.Types;
|
||||||
using TelegramBotBase.Base;
|
using TelegramBotBase.Base;
|
||||||
|
using TelegramBotBase.Enums;
|
||||||
|
|
||||||
namespace TelegramBotBase.Form
|
namespace TelegramBotBase.Form
|
||||||
{
|
{
|
||||||
@@ -19,37 +20,7 @@ namespace TelegramBotBase.Form
|
|||||||
|
|
||||||
public eSide DeleteSide { get; set; }
|
public eSide DeleteSide { get; set; }
|
||||||
|
|
||||||
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 AutoCleanForm()
|
public AutoCleanForm()
|
||||||
{
|
{
|
||||||
@@ -57,9 +28,14 @@ namespace TelegramBotBase.Form
|
|||||||
this.DeleteMode = eDeleteMode.OnEveryCall;
|
this.DeleteMode = eDeleteMode.OnEveryCall;
|
||||||
this.DeleteSide = eSide.BotOnly;
|
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)
|
if (this.Device == null)
|
||||||
return;
|
return;
|
||||||
@@ -127,7 +103,7 @@ namespace TelegramBotBase.Form
|
|||||||
this.OldMessages.RemoveAt(this.OldMessages.Count - 1);
|
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)
|
if (this.DeleteMode != eDeleteMode.OnLeavingForm)
|
||||||
return;
|
return;
|
||||||
@@ -135,7 +111,6 @@ namespace TelegramBotBase.Form
|
|||||||
await MessageCleanup();
|
await MessageCleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Cleans up all remembered messages.
|
/// Cleans up all remembered messages.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Telegram.Bot.Types.ReplyMarkups;
|
||||||
|
|
||||||
namespace TelegramBotBase.Form
|
namespace TelegramBotBase.Form
|
||||||
{
|
{
|
||||||
@@ -15,15 +16,35 @@ namespace TelegramBotBase.Form
|
|||||||
|
|
||||||
public String Value { get; set; }
|
public String Value { get; set; }
|
||||||
|
|
||||||
|
public String Url { get; set; }
|
||||||
|
|
||||||
public ButtonBase()
|
public ButtonBase()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ButtonBase(String Text, String Value)
|
public ButtonBase(String Text, String Value, String Url = null)
|
||||||
{
|
{
|
||||||
this.Text = Text;
|
this.Text = Text;
|
||||||
this.Value = Value;
|
this.Value = Value;
|
||||||
|
this.Url = Url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public InlineKeyboardButton ToInlineButton()
|
||||||
|
{
|
||||||
|
if (this.Url == null)
|
||||||
|
{
|
||||||
|
return InlineKeyboardButton.WithCallbackData(this.Text, this.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
var ikb = new InlineKeyboardButton();
|
||||||
|
|
||||||
|
ikb.Text = this.Text;
|
||||||
|
ikb.Url = this.Url;
|
||||||
|
|
||||||
|
return ikb;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,14 +14,18 @@ namespace TelegramBotBase.Form
|
|||||||
{
|
{
|
||||||
List<List<ButtonBase>> Buttons = new List<List<ButtonBase>>();
|
List<List<ButtonBase>> Buttons = new List<List<ButtonBase>>();
|
||||||
|
|
||||||
|
|
||||||
|
public IReplyMarkup Markup { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public ButtonForm()
|
public ButtonForm()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddButtonRow(List<ButtonBase> row)
|
public void AddButtonRow(IEnumerable<ButtonBase> row)
|
||||||
{
|
{
|
||||||
Buttons.Add(row);
|
Buttons.Add(row.ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddButtonRow(params ButtonBase[] row)
|
public void AddButtonRow(params ButtonBase[] row)
|
||||||
@@ -66,13 +70,16 @@ namespace TelegramBotBase.Form
|
|||||||
|
|
||||||
public InlineKeyboardButton[][] ToArray()
|
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()).ToArray()).ToArray();
|
||||||
|
|
||||||
return ikb;
|
return ikb;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator InlineKeyboardMarkup(ButtonForm form)
|
public static implicit operator InlineKeyboardMarkup(ButtonForm form)
|
||||||
{
|
{
|
||||||
|
if (form == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
InlineKeyboardMarkup ikm = new InlineKeyboardMarkup(form.ToArray());
|
InlineKeyboardMarkup ikm = new InlineKeyboardMarkup(form.ToArray());
|
||||||
|
|
||||||
return ikm;
|
return ikm;
|
||||||
|
|||||||
@@ -67,9 +67,9 @@ namespace TelegramBotBase
|
|||||||
DeviceSession ds = new Sessions.DeviceSession(deviceId, start);
|
DeviceSession ds = new Sessions.DeviceSession(deviceId, start);
|
||||||
|
|
||||||
start.Device = ds;
|
start.Device = ds;
|
||||||
await start.Init();
|
await start.OnInit(new InitEventArgs());
|
||||||
|
|
||||||
await start.Opened();
|
await start.OnOpened(new EventArgs());
|
||||||
|
|
||||||
this[deviceId] = ds;
|
this[deviceId] = ds;
|
||||||
return ds;
|
return ds;
|
||||||
|
|||||||
@@ -127,11 +127,7 @@ namespace TelegramBotBase.Sessions
|
|||||||
if (this.ActiveForm == null)
|
if (this.ActiveForm == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
InlineKeyboardMarkup markup = null;
|
InlineKeyboardMarkup markup = buttons;
|
||||||
if (buttons != null)
|
|
||||||
{
|
|
||||||
markup = buttons;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -160,11 +156,7 @@ namespace TelegramBotBase.Sessions
|
|||||||
if (this.ActiveForm == null)
|
if (this.ActiveForm == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
InlineKeyboardMarkup markup = null;
|
InlineKeyboardMarkup markup = buttons;
|
||||||
if (buttons != null)
|
|
||||||
{
|
|
||||||
markup = buttons;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -194,11 +186,7 @@ namespace TelegramBotBase.Sessions
|
|||||||
if (this.ActiveForm == null)
|
if (this.ActiveForm == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
InlineKeyboardMarkup markup = null;
|
InlineKeyboardMarkup markup = buttons;
|
||||||
if (buttons != null)
|
|
||||||
{
|
|
||||||
markup = buttons;
|
|
||||||
}
|
|
||||||
|
|
||||||
Message m = null;
|
Message m = null;
|
||||||
|
|
||||||
@@ -253,6 +241,39 @@ namespace TelegramBotBase.Sessions
|
|||||||
return m;
|
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)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sends an image
|
/// Sends an image
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -266,11 +287,7 @@ namespace TelegramBotBase.Sessions
|
|||||||
if (this.ActiveForm == null)
|
if (this.ActiveForm == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
InlineKeyboardMarkup markup = null;
|
InlineKeyboardMarkup markup = buttons;
|
||||||
if (buttons != null)
|
|
||||||
{
|
|
||||||
markup = buttons;
|
|
||||||
}
|
|
||||||
|
|
||||||
Message m = null;
|
Message m = null;
|
||||||
|
|
||||||
|
|||||||
@@ -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: 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: 2.6 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 5.7 KiB |