docs: fix anchors
This commit is contained in:
parent
869d16fa02
commit
a125addd2e
136
README.md
136
README.md
@ -30,15 +30,14 @@ BitTorrent: `TYVZSykaVT1nKZnz9hjDgBRNB9VavU1bpW`
|
|||||||
|
|
||||||
## Index
|
## Index
|
||||||
|
|
||||||
- [Introduction](#introduction)
|
- [Quick start](#quick-start)
|
||||||
- [How to Start](#how-to-start)
|
- [Simplified builder](#simplified-builder)
|
||||||
- [Quick Start](#quick-start)
|
- [Features](#features)
|
||||||
- [Message Handling](#message-handling)
|
* [System calls & bot commands](#system-calls--bot-commands)
|
||||||
* [Example #0 - System Calls](#add-some-system-calls-example-0---system-calls)
|
* [Text messages handling](#text-messages)
|
||||||
* [Example #1 - Simple text messages](#lets-start-with-text-messages-example-1---simple-test)
|
* [Buttons](#buttons)
|
||||||
* [Example #2 - Button test](#now-some-buttons-example-2---button-test)
|
* [Custom controls](#custom-controls)
|
||||||
* [Example #3 - Progress Bar control](#now-some-controls-example-3---progress-bar-test)
|
* [Forms advanced](#forms-advanced)
|
||||||
* [Example #4 - Registration Formular](#registration-example-example-4---registration-form-test)
|
|
||||||
- [Special Forms](#forms)
|
- [Special Forms](#forms)
|
||||||
* [AlertDialog](#alert-dialog)
|
* [AlertDialog](#alert-dialog)
|
||||||
* [AutoCleanForm](#autocleanform)
|
* [AutoCleanForm](#autocleanform)
|
||||||
@ -71,12 +70,12 @@ BitTorrent: `TYVZSykaVT1nKZnz9hjDgBRNB9VavU1bpW`
|
|||||||
* [IgnoreState](#ignorestate)
|
* [IgnoreState](#ignorestate)
|
||||||
- [Navigation and NavigationController (v4.0.0)](#navigation-and-navigationcontroller)
|
- [Navigation and NavigationController (v4.0.0)](#navigation-and-navigationcontroller)
|
||||||
* [As of Now](#as-of-now)
|
* [As of Now](#as-of-now)
|
||||||
* [How to use](#how-to-use-)
|
* [Usage](#usage)
|
||||||
- [Examples](#examples)
|
- [Examples](#examples)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## How to start
|
## Quick start
|
||||||
|
|
||||||
First of all, create a new empty dotnet console project and paste some code:
|
First of all, create a new empty dotnet console project and paste some code:
|
||||||
|
|
||||||
@ -120,7 +119,7 @@ public class StartForm : FormBase
|
|||||||
public override async Task PreLoad(MessageResult message)
|
public override async Task PreLoad(MessageResult message)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets invoked on every Message/Action/Data in this context
|
// Gets invoked on every Message/Action/Data in this context
|
||||||
public override async Task Load(MessageResult message)
|
public override async Task Load(MessageResult message)
|
||||||
{
|
{
|
||||||
@ -132,17 +131,17 @@ public class StartForm : FormBase
|
|||||||
public override async Task Edited(MessageResult message)
|
public override async Task Edited(MessageResult message)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets invoked on Button clicks
|
// Gets invoked on Button clicks
|
||||||
public override async Task Action(MessageResult message)
|
public override async Task Action(MessageResult message)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets invoked on Data uploades by the user (of type Photo, Audio, Video, Contact, Location, Document)
|
// Gets invoked on Data uploades by the user (of type Photo, Audio, Video, Contact, Location, Document)
|
||||||
public override async Task SentData(DataResult data)
|
public override async Task SentData(DataResult data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//Gets invoked on every Message/Action/Data to render Design or Response
|
//Gets invoked on every Message/Action/Data to render Design or Response
|
||||||
public override async Task Render(MessageResult message)
|
public override async Task Render(MessageResult message)
|
||||||
{
|
{
|
||||||
@ -164,7 +163,7 @@ var form = new TestForm();
|
|||||||
await this.NavigateTo(form);
|
await this.NavigateTo(form);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Quick Start:
|
## Simplified builder
|
||||||
|
|
||||||
When migrating from a previous version or starting completely new, all these options can be a bit overwhelming.
|
When migrating from a previous version or starting completely new, all these options can be a bit overwhelming.
|
||||||
There's a function called `QuickStart` that simplifies building a bit.
|
There's a function called `QuickStart` that simplifies building a bit.
|
||||||
@ -178,6 +177,8 @@ var bot = BotBaseBuilder
|
|||||||
bot.Start();
|
bot.Start();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
### System calls & bot commands
|
### System calls & bot commands
|
||||||
|
|
||||||
Using BotFather you can add *Commands* to your bot. The user will see them as popups in a dialog.
|
Using BotFather you can add *Commands* to your bot. The user will see them as popups in a dialog.
|
||||||
@ -227,11 +228,10 @@ bot.BotCommand += async (s, en) =>
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "/params":
|
case "/params":
|
||||||
String m = en.Parameters.DefaultIfEmpty("").Aggregate((a, b) => a + " and " + b);
|
string m = en.Parameters.DefaultIfEmpty("").Aggregate((a, b) => a + " and " + b);
|
||||||
await en.Device.Send("Your parameters are " + m, replyTo: en.Device.LastMessage);
|
await en.Device.Send("Your parameters are " + m, replyTo: en.Device.LastMessage);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
await bot.UploadBotCommands()
|
await bot.UploadBotCommands()
|
||||||
@ -256,7 +256,7 @@ public class SimpleForm : AutoCleanForm
|
|||||||
|
|
||||||
this.Opened += SimpleForm_Opened;
|
this.Opened += SimpleForm_Opened;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SimpleForm_Opened(object sender, EventArgs e)
|
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");
|
||||||
@ -288,7 +288,6 @@ public class SimpleForm : AutoCleanForm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Buttons
|
### Buttons
|
||||||
@ -369,68 +368,68 @@ public class ProgressTest : AutoCleanForm
|
|||||||
{
|
{
|
||||||
this.DeleteMode = eDeleteMode.OnLeavingForm;
|
this.DeleteMode = eDeleteMode.OnLeavingForm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Opened()
|
public override async Task Opened()
|
||||||
{
|
{
|
||||||
await this.Device.Send("Welcome to ProgressTest");
|
await this.Device.Send("Welcome to ProgressTest");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Action(MessageResult message)
|
public override async Task Action(MessageResult message)
|
||||||
{
|
{
|
||||||
var call = message.GetData<CallbackData>();
|
var call = message.GetData<CallbackData>();
|
||||||
await message.ConfirmAction();
|
await message.ConfirmAction();
|
||||||
|
|
||||||
if (call == null) return;
|
if (call == null) return;
|
||||||
|
|
||||||
TelegramBotBase.Controls.ProgressBar Bar = null;
|
TelegramBotBase.Controls.ProgressBar Bar = null;
|
||||||
|
|
||||||
switch (call.Value)
|
switch (call.Value)
|
||||||
{
|
{
|
||||||
case "standard":
|
case "standard":
|
||||||
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.standard);
|
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.standard);
|
||||||
Bar.Device = this.Device;
|
Bar.Device = this.Device;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "squares":
|
case "squares":
|
||||||
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.squares);
|
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.squares);
|
||||||
Bar.Device = this.Device;
|
Bar.Device = this.Device;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "circles":
|
case "circles":
|
||||||
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.circles);
|
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.circles);
|
||||||
Bar.Device = this.Device;
|
Bar.Device = this.Device;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "lines":
|
case "lines":
|
||||||
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.lines);
|
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.lines);
|
||||||
Bar.Device = this.Device;
|
Bar.Device = this.Device;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "squaredlines":
|
case "squaredlines":
|
||||||
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.squaredLines);
|
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.squaredLines);
|
||||||
Bar.Device = this.Device;
|
Bar.Device = this.Device;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "start":
|
case "start":
|
||||||
var sf = new Start();
|
var sf = new Start();
|
||||||
await sf.Init();
|
await sf.Init();
|
||||||
await this.NavigateTo(sf);
|
await this.NavigateTo(sf);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render Progress bar and show some "example" progress
|
// Render Progress bar and show some "example" progress
|
||||||
await Bar.Render();
|
await Bar.Render();
|
||||||
|
|
||||||
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();
|
||||||
|
|
||||||
Thread.Sleep(250);
|
Thread.Sleep(250);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -438,12 +437,12 @@ public class ProgressTest : AutoCleanForm
|
|||||||
public override async Task Render(MessageResult message)
|
public override async Task Render(MessageResult message)
|
||||||
{
|
{
|
||||||
ButtonForm btn = new ButtonForm();
|
ButtonForm btn = new ButtonForm();
|
||||||
|
|
||||||
btn.AddButtonRow(new ButtonBase("Standard", new CallbackData("a", "standard").Serialize()), new ButtonBase("Squares", new CallbackData("a", "squares").Serialize()));
|
btn.AddButtonRow(new ButtonBase("Standard", new CallbackData("a", "standard").Serialize()), new ButtonBase("Squares", new CallbackData("a", "squares").Serialize()));
|
||||||
btn.AddButtonRow(new ButtonBase("Circles", new CallbackData("a", "circles").Serialize()), new ButtonBase("Lines", new CallbackData("a", "lines").Serialize()));
|
btn.AddButtonRow(new ButtonBase("Circles", new CallbackData("a", "circles").Serialize()), new ButtonBase("Lines", new CallbackData("a", "lines").Serialize()));
|
||||||
btn.AddButtonRow(new ButtonBase("Squared Line", new CallbackData("a", "squaredlines").Serialize()));
|
btn.AddButtonRow(new ButtonBase("Squared Line", new CallbackData("a", "squaredlines").Serialize()));
|
||||||
btn.AddButtonRow(new ButtonBase("Back to start", new CallbackData("a", "start").Serialize()));
|
btn.AddButtonRow(new ButtonBase("Back to start", new CallbackData("a", "start").Serialize()));
|
||||||
|
|
||||||
await this.Device.Send("Choose your progress bar:", btn);
|
await this.Device.Send("Choose your progress bar:", btn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,7 +452,7 @@ public class ProgressTest : AutoCleanForm
|
|||||||
{
|
{
|
||||||
await b.Cleanup();
|
await b.Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.Device.Send("Ciao from ProgressTest");
|
await this.Device.Send("Ciao from ProgressTest");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -474,42 +473,42 @@ Registration forms have never been so easy.
|
|||||||
```csharp
|
```csharp
|
||||||
public class PerForm : AutoCleanForm
|
public class PerForm : AutoCleanForm
|
||||||
{
|
{
|
||||||
public String EMail { get; set; }
|
public string EMail { get; set; }
|
||||||
|
|
||||||
public String Firstname { get; set; }
|
public string Firstname { get; set; }
|
||||||
|
|
||||||
public String Lastname { get; set; }
|
public string Lastname { get; set; }
|
||||||
|
|
||||||
public async override Task Load(MessageResult message)
|
public async override Task Load(MessageResult message)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(message.MessageText)) return;
|
if (string.IsNullOrWhiteSpace(message.MessageText)) return;
|
||||||
|
|
||||||
if (this.Firstname == null)
|
if (this.Firstname == null)
|
||||||
{
|
{
|
||||||
this.Firstname = message.MessageText;
|
this.Firstname = message.MessageText;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.Lastname == null)
|
if (this.Lastname == null)
|
||||||
{
|
{
|
||||||
this.Lastname = message.MessageText;
|
this.Lastname = message.MessageText;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.EMail == null)
|
if (this.EMail == null)
|
||||||
{
|
{
|
||||||
this.EMail = message.MessageText;
|
this.EMail = message.MessageText;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async override Task Action(MessageResult message)
|
public async override Task Action(MessageResult message)
|
||||||
{
|
{
|
||||||
var call = message.GetData<CallbackData>();
|
var call = message.GetData<CallbackData>();
|
||||||
await message.ConfirmAction();
|
await message.ConfirmAction();
|
||||||
|
|
||||||
if (call == null) return;
|
if (call == null) return;
|
||||||
|
|
||||||
switch (call.Value)
|
switch (call.Value)
|
||||||
{
|
{
|
||||||
case "back":
|
case "back":
|
||||||
@ -518,7 +517,7 @@ public class PerForm : AutoCleanForm
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async override Task Render(MessageResult message)
|
public async override Task Render(MessageResult message)
|
||||||
{
|
{
|
||||||
if (this.Firstname == null)
|
if (this.Firstname == null)
|
||||||
@ -526,28 +525,28 @@ public class PerForm : AutoCleanForm
|
|||||||
await this.Device.Send("Please sent your firstname:");
|
await this.Device.Send("Please sent your firstname:");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.Lastname == null)
|
if (this.Lastname == null)
|
||||||
{
|
{
|
||||||
await this.Device.Send("Please sent your lastname:");
|
await this.Device.Send("Please sent your lastname:");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.EMail == null)
|
if (this.EMail == null)
|
||||||
{
|
{
|
||||||
await this.Device.Send("Please sent your email address:");
|
await this.Device.Send("Please sent your email address:");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string s = "";
|
string s = "";
|
||||||
|
|
||||||
s += "Firstname: " + this.Firstname + "\r\n";
|
s += "Firstname: " + this.Firstname + "\r\n";
|
||||||
s += "Lastname: " + this.Lastname + "\r\n";
|
s += "Lastname: " + this.Lastname + "\r\n";
|
||||||
s += "E-Mail: " + this.EMail + "\r\n";
|
s += "E-Mail: " + this.EMail + "\r\n";
|
||||||
|
|
||||||
ButtonForm bf = new ButtonForm();
|
ButtonForm bf = new ButtonForm();
|
||||||
bf.AddButtonRow(new ButtonBase("Back", new CallbackData("a", "back").Serialize()));
|
bf.AddButtonRow(new ButtonBase("Back", new CallbackData("a", "back").Serialize()));
|
||||||
|
|
||||||
await this.Device.Send("Your details:\r\n" + s, bf);
|
await this.Device.Send("Your details:\r\n" + s, bf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -711,7 +710,7 @@ public class Start : SplitterForm
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task<bool> OpenChannel(MessageResult e)
|
public override Task<bool> OpenChannel(MessageResult e)
|
||||||
{
|
{
|
||||||
return base.OpenChannel(e);
|
return base.OpenChannel(e);
|
||||||
@ -874,7 +873,7 @@ serialization process.
|
|||||||
public interface IStateMachine
|
public interface IStateMachine
|
||||||
{
|
{
|
||||||
void SaveFormStates(SaveStatesEventArgs e);
|
void SaveFormStates(SaveStatesEventArgs e);
|
||||||
|
|
||||||
StateContainer LoadFormStates();
|
StateContainer LoadFormStates();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -895,7 +894,8 @@ public interface IStateForm
|
|||||||
|
|
||||||
### Attributes
|
### Attributes
|
||||||
|
|
||||||
If you don't want to implement the `IStateForm` interface, because there are maybe *just* one or two properties you want to
|
If you don't want to implement the `IStateForm` interface, because there are maybe *just* one or two properties you want
|
||||||
|
to
|
||||||
keep and restore, use the following attributes.
|
keep and restore, use the following attributes.
|
||||||
|
|
||||||
#### SaveState
|
#### SaveState
|
||||||
@ -918,7 +918,6 @@ class and it will not get serialized, even if it implements IStateForm or the Sa
|
|||||||
[IgnoreState]
|
[IgnoreState]
|
||||||
public class Registration : STForm
|
public class Registration : STForm
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -942,7 +941,8 @@ details and latest matches.
|
|||||||
|
|
||||||
After the matches, you want to maybe switch to different teams and take a look at their statistics and matches.
|
After the matches, you want to maybe switch to different teams and take a look at their statistics and matches.
|
||||||
|
|
||||||
At some point, you *just* want to get back to the first team so like on Android you're clicking the "back" button multiple
|
At some point, you *just* want to get back to the first team so like on Android you're clicking the "back" button
|
||||||
|
multiple
|
||||||
times.
|
times.
|
||||||
|
|
||||||
This can become really complicated, when not having some controller below which handle these "Push/Pop" calls.
|
This can become really complicated, when not having some controller below which handle these "Push/Pop" calls.
|
||||||
@ -985,8 +985,10 @@ When you want to go back one Form on the stack use `PopAsync`:
|
|||||||
await this.NavigationController.PopAsync();
|
await this.NavigationController.PopAsync();
|
||||||
```
|
```
|
||||||
|
|
||||||
**Notice**: *By default the `NavigationController` has `ForceCleanupOnLastPop` enabled, which means that when the stack is
|
**Notice**: *By default the `NavigationController` has `ForceCleanupOnLastPop` enabled, which means that when the stack
|
||||||
again at 1 (due to `PopAsync` or `PopToRootAsync` calls) it will replace the controller automatically with the root form you
|
is
|
||||||
|
again at 1 (due to `PopAsync` or `PopToRootAsync` calls) it will replace the controller automatically with the root form
|
||||||
|
you
|
||||||
have given to the constructor at the beginning.*
|
have given to the constructor at the beginning.*
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
@ -1007,11 +1009,3 @@ Will delete Join and Leave messages automatically in groups.
|
|||||||
Example using minimal dotnet console template with EntityFramework and Dependency Injection.
|
Example using minimal dotnet console template with EntityFramework and Dependency Injection.
|
||||||
|
|
||||||
- [Examples/EFCore/](Examples/EFCore/)
|
- [Examples/EFCore/](Examples/EFCore/)
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
I will add more notes to it soon, so stay tuned.
|
|
||||||
|
|
||||||
Warm regards
|
|
||||||
|
|
||||||
Florian Dahn
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user