Compare commits

..
27 Commits
Author SHA1 Message Date
Florian Zevedei 2a873cc29b Merge pull request #53 from MajMcCloud/development
Integrating development branch into master
2023-12-06 15:23:47 +01:00
Florian Zevedei f401216eff Fixing EditMessage behaviour 2023-12-06 15:19:28 +01:00
Florian Zevedei 0cb4f02a8d Merge pull request #52 from contributeless/fix/get-device-id-from-edited-message
Fix: get chat id from edited message
2023-12-06 15:17:17 +01:00
TCSBANK\e.khudik 62b6bafbd3 Fix: get chat id from edited message 2023-12-05 13:02:53 +03:00
Florian Zevedei 43f4ab1061 Update README.md 2023-11-26 15:09:42 +01:00
Florian Zevedei 1f438186f4 Merge pull request #50 from MajMcCloud/master
Merging master changes into development branch
2023-11-26 15:08:56 +01:00
Florian Zevedei f447b058d0 Update README.md 2023-11-26 15:08:40 +01:00
Florian Zevedei 40ba9bd8ab Update README.md 2023-11-26 15:07:43 +01:00
Florian Zevedei ca473f78ed Adding /start command handling to test project 2023-11-02 14:52:05 +01:00
Florian Zevedei ab702dbc9f Added missing UsePersian method to interface. 2023-11-01 01:09:35 +01:00
Florian Zevedei 23dc1ff1d6 Merge pull request #48 from mottaghipour/master
[LANGUAGE] implement Persian language class
2023-11-01 01:01:25 +01:00
AmirAbbas e044d725c9 [FEATURE] add UsePersian method to BotBaseBuilder class 2023-10-31 13:25:46 +03:30
AmirAbbas 4825beea7e [FEATURE] implement Persian language class 2023-10-31 13:23:41 +03:30
AmirAbbas 78d65868ff [BASE] Init Persian language class 2023-10-31 13:11:02 +03:30
AmirAbbas d7aca80d59 [REFACTOR] convert language classes to language sealed classes 2023-10-31 13:10:31 +03:30
Florian Zevedei 73863c4154 Adding project files 2023-09-29 18:40:56 +02:00
Florian Zevedei e3b1a32535 Adding missing Program.cs 2023-09-29 18:40:20 +02:00
Florian Zevedei 571049eeb4 Replacing exception text with nameof litteral 2023-09-29 18:34:33 +02:00
Florian Zevedei 30222d640d Adding full DI navigation example for testing purposes.
- adding internal private field into FormBase class
- adding Extension methods into DependencyInjection namespace for use
- adding 2 NavigateTo extension methods for DI using ServiceProvider
- adding example project
- adding to readme as example
2023-09-29 18:34:10 +02:00
Florian Zevedei e6a48115a6 Adding xml comments to BotBase 2023-09-29 18:28:55 +02:00
Florian Zevedei b278015dd4 Replacing static names in exception messages with nameof literal 2023-09-29 18:26:39 +02:00
Florian Zevedei 91e0c54728 Merge pull request #46 from MajMcCloud/development
Migrate development to master
2023-09-16 17:22:01 +02:00
Florian Zevedei 788f935c02 Add latest nuget package instead of local project to extensions 2023-09-16 17:11:40 +02:00
Florian Zevedei d1089fe716 editing Label example project 2023-09-16 17:11:21 +02:00
Florian Zevedei 1d3db0116e Update README.md 2023-09-15 18:52:15 +02:00
Florian Zevedei e95301f727 Update README.md 2023-09-15 18:50:16 +02:00
Florian Zevedei 4ba91803fe Update README.md 2023-09-13 15:13:22 +02:00
30 changed files with 442 additions and 27 deletions
@@ -0,0 +1,12 @@
using Microsoft.EntityFrameworkCore;
namespace DependencyInjection.Database;
public class BotDbContext : DbContext
{
public BotDbContext(DbContextOptions options) : base(options)
{
}
public DbSet<User> Users { get; set; }
}
@@ -0,0 +1,7 @@
namespace DependencyInjection.Database;
public class User
{
public long Id { get; set; }
public string LastMessage { get; set; }
}
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.11" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\TelegramBotBase\TelegramBotBase.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,67 @@
using DependencyInjection.Database;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
using TelegramBotBase.DependencyInjection;
namespace DependencyInjection.Forms
{
public class ConfirmationForm : FormBase
{
private readonly BotDbContext _dbContext;
public ConfirmationForm(BotDbContext dbContext)
{
_dbContext = dbContext;
}
public override async Task Load(MessageResult message)
{
var user = await _dbContext.Users.FindAsync(Device.DeviceId);
if (user == null)
{
await this.NavigateTo<StartForm>();
return;
}
}
public override async Task Action(MessageResult message)
{
await message.ConfirmAction("Go back");
switch (message.RawData)
{
case "back":
await this.NavigateTo<StartForm>();
break;
}
}
public override async Task Render(MessageResult message)
{
var user = await _dbContext.Users.FindAsync(Device.DeviceId);
if (user == null)
return;
var bf = new ButtonForm();
bf.AddButtonRow("Back", "back");
await Device.Send($"ConfirmationForm: Your last message was: {user.LastMessage}. Click \"Back\" to get back.", bf);
}
}
}
+35
View File
@@ -0,0 +1,35 @@
using DependencyInjection.Database;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using TelegramBotBase.Builder;
namespace DependencyInjection
{
internal class Program
{
static async Task Main(string[] args)
{
var serviceCollection = new ServiceCollection()
.AddDbContext<BotDbContext>(x => x.UseInMemoryDatabase("TelegramBotBase"));
var serviceProvider = serviceCollection.BuildServiceProvider();
var bot = BotBaseBuilder.Create()
.WithAPIKey(Environment.GetEnvironmentVariable("API_KEY") ??
throw new Exception("API_KEY is not set"))
.DefaultMessageLoop()
.WithServiceProvider<StartForm>(serviceProvider)
.NoProxy()
.NoCommands()
.NoSerialization()
.DefaultLanguage()
.Build();
await bot.Start();
await Task.Delay(-1);
}
}
}
+79
View File
@@ -0,0 +1,79 @@
using DependencyInjection.Database;
using DependencyInjection.Forms;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
using TelegramBotBase.DependencyInjection;
namespace DependencyInjection;
public class StartForm : FormBase
{
private readonly BotDbContext _dbContext;
public StartForm(BotDbContext dbContext)
{
_dbContext = dbContext;
}
public override async Task Load(MessageResult message)
{
var user = await _dbContext.Users.FindAsync(Device.DeviceId);
if (user is null)
{
user = new User
{
Id = Device.DeviceId,
LastMessage = "<unknown>"
};
_dbContext.Users.Add(user);
await _dbContext.SaveChangesAsync();
}
if (message.IsAction)
return;
user.LastMessage = string.IsNullOrWhiteSpace(message.MessageText) ? "<unknown>" : message.MessageText;
await _dbContext.SaveChangesAsync();
}
public override async Task Action(MessageResult message)
{
await message.ConfirmAction("Ok");
switch(message.RawData)
{
case "open":
await this.NavigateTo(typeof(ConfirmationForm));
var new_form = await this.NavigateTo<ConfirmationForm>();
if (new_form == null)
{
await Device.Send("Cant open ConfirmationForm");
}
break;
}
}
public override async Task Render(MessageResult message)
{
var user = await _dbContext.Users.FindAsync(Device.DeviceId);
if (user == null)
return;
var bf = new ButtonForm();
bf.AddButtonRow("Open confirmation", "open");
await Device.Send($"Your last message's text was: `{user.LastMessage}`", bf);
}
}
@@ -27,6 +27,8 @@ namespace InlineAndReplyCombination
await BotBaseInstance.UploadBotCommands(); await BotBaseInstance.UploadBotCommands();
BotBaseInstance.BotCommand += BotBaseInstance_BotCommand;
await BotBaseInstance.Start(); await BotBaseInstance.Start();
@@ -37,5 +39,28 @@ namespace InlineAndReplyCombination
await BotBaseInstance.Stop(); await BotBaseInstance.Stop();
} }
private static async Task BotBaseInstance_BotCommand(object sender, TelegramBotBase.Args.BotCommandEventArgs e)
{
switch(e.Command)
{
case "/start":
var start = new StartForm();
await e.Device.ActiveForm.NavigateTo(start);
break;
}
}
} }
} }
+9 -2
View File
@@ -1,6 +1,6 @@
# .NET Telegram Bot Framework - Context based addon # .NET Telegram Bot Framework - Context based addon
[![NuGet version (TelegramBotBase)](https://img.shields.io/nuget/v/TelegramBotBase.svg?style=flat-square)](https://www.nuget.org/packages/TelegramBotBase/) [![NuGet version (TelegramBotBase)](https://img.shields.io/nuget/vpre/TelegramBotBase.svg?style=flat-square)](https://www.nuget.org/packages/TelegramBotBase/)
[![Telegram chat](https://img.shields.io/badge/Support_Chat-Telegram-blue.svg?style=flat-square)](https://www.t.me/tgbotbase) [![Telegram chat](https://img.shields.io/badge/Support_Chat-Telegram-blue.svg?style=flat-square)](https://www.t.me/tgbotbase)
[![License](https://img.shields.io/github/license/MajMcCloud/telegrambotframework.svg?style=flat-square&maxAge=2592000&label=License)](https://raw.githubusercontent.com/MajMcCloud/TelegramBotFramework/master/LICENCE.md) [![License](https://img.shields.io/github/license/MajMcCloud/telegrambotframework.svg?style=flat-square&maxAge=2592000&label=License)](https://raw.githubusercontent.com/MajMcCloud/TelegramBotFramework/master/LICENCE.md)
@@ -16,6 +16,8 @@
## Donate ## Donate
Paypal: [https://paypal.me/majmccloud](https://paypal.me/majmccloud)
Bitcoin: `1GoUJYMwAvBipQTfw2FKydAz12J8RDyeJs` / `bc1qqwlp0p5ley29lsu6jhe0qv7s7963kfc7d0m53d` Bitcoin: `1GoUJYMwAvBipQTfw2FKydAz12J8RDyeJs` / `bc1qqwlp0p5ley29lsu6jhe0qv7s7963kfc7d0m53d`
Etherium: `0xAf3835104c2C3E5b3e721FA2c7365955e87DB931` Etherium: `0xAf3835104c2C3E5b3e721FA2c7365955e87DB931`
@@ -641,7 +643,7 @@ await this.NavigateTo(cd);
A minimal control which allows to manage a classic "text" message and update its later without having to keep track of the message id. A minimal control which allows to manage a classic "text" message and update its later without having to keep track of the message id.
<img src=".github/images/label.gif?raw=true" /> <img src=".github/images/label.gif?raw=true" style="width:500px" />
Check the example project [TelegramBotBase.Test/Tests/Controls/LabelForm.cs](TelegramBotBase.Test/Tests/Controls/LabelForm.cs) Check the example project [TelegramBotBase.Test/Tests/Controls/LabelForm.cs](TelegramBotBase.Test/Tests/Controls/LabelForm.cs)
@@ -1081,3 +1083,8 @@ Having already a web application and want to add a TelegramBot side-by-side with
Want to use Inline- and ReplyMarkup at the same time ? Here is an example how you can do that: Want to use Inline- and ReplyMarkup at the same time ? Here is an example how you can do that:
- [Examples/InlineAndReplyCombination](Examples/InlineAndReplyCombination) - [Examples/InlineAndReplyCombination](Examples/InlineAndReplyCombination)
Alpha: Full Dependency Injection example within this framework.
- [Examples/DependencyInjection](Examples/DependencyInjection)
@@ -15,10 +15,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="System.Drawing.Common" Version="6.0.0" /> <PackageReference Include="System.Drawing.Common" Version="6.0.0" />
</ItemGroup> <PackageReference Include="TelegramBotBase" Version="6.0.0" />
<ItemGroup>
<ProjectReference Include="..\TelegramBotBase\TelegramBotBase.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -31,7 +31,7 @@ namespace TelegramBotBase.Extensions.Serializer.Database.MSSQL
if (FallbackStateForm != null && !FallbackStateForm.IsSubclassOf(typeof(FormBase))) if (FallbackStateForm != null && !FallbackStateForm.IsSubclassOf(typeof(FormBase)))
{ {
throw new ArgumentException("FallbackStateForm is not a subclass of FormBase"); throw new ArgumentException($"{nameof(FallbackStateForm)} is not a subclass of {nameof(FormBase)}");
} }
} }
@@ -16,15 +16,12 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.0.0"/> <PackageReference Include="Microsoft.Data.SqlClient" Version="5.0.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1"> <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
</ItemGroup> <PackageReference Include="TelegramBotBase" Version="6.0.0" />
<ItemGroup>
<ProjectReference Include="..\TelegramBotBase\TelegramBotBase.csproj"/>
</ItemGroup> </ItemGroup>
</Project> </Project>
@@ -11,7 +11,7 @@ namespace TelegramBotBase.Example.Tests.Controls;
public class LabelForm : AutoCleanForm public class LabelForm : AutoCleanForm
{ {
TelegramBotBase.Controls.Inline.LabelControl _label; TelegramBotBase.Controls.Inline.Label _label;
ButtonGrid _buttonGrid; ButtonGrid _buttonGrid;
@@ -27,7 +27,7 @@ public class LabelForm : AutoCleanForm
private Task LabelForm_Init(object sender, InitEventArgs e) private Task LabelForm_Init(object sender, InitEventArgs e)
{ {
//The "label" control //The "label" control
_label = new LabelControl("My test label"); _label = new Label("My test label");
AddControl(_label); AddControl(_label);
+2
View File
@@ -32,6 +32,8 @@ public class FormBase : IDisposable
public MessageClient Client { get; set; } public MessageClient Client { get; set; }
IServiceProvider _serviceProvider = null;
/// <summary> /// <summary>
/// has this formular already been disposed ? /// has this formular already been disposed ?
/// </summary> /// </summary>
+1
View File
@@ -16,6 +16,7 @@ public class UpdateResult : ResultBase
/// </summary> /// </summary>
public override long DeviceId => public override long DeviceId =>
RawData?.Message?.Chat?.Id RawData?.Message?.Chat?.Id
?? RawData?.EditedMessage?.Chat?.Id
?? RawData?.CallbackQuery?.Message?.Chat?.Id ?? RawData?.CallbackQuery?.Message?.Chat?.Id
?? Device?.DeviceId ?? Device?.DeviceId
?? 0; ?? 0;
+10 -1
View File
@@ -39,7 +39,10 @@ public class BotBaseBuilder : IAPIKeySelectionStage, IMessageLoopSelectionStage,
/// </summary> /// </summary>
private Dictionary<BotCommandScope, List<BotCommand>> BotCommandScopes { get; } = new(); private Dictionary<BotCommandScope, List<BotCommand>> BotCommandScopes { get; } = new();
/// <summary>
/// Creates a full BotBase instance with all parameters previously set.
/// </summary>
/// <returns></returns>
public BotBase Build() public BotBase Build()
{ {
var bot = new BotBase(_apiKey, _client) var bot = new BotBase(_apiKey, _client)
@@ -400,6 +403,12 @@ public class BotBaseBuilder : IAPIKeySelectionStage, IMessageLoopSelectionStage,
return this; return this;
} }
public IBuildingStage UsePersian()
{
Default.Language = new Persian();
return this;
}
public IBuildingStage Custom(Localization language) public IBuildingStage Custom(Localization language)
{ {
Default.Language = language; Default.Language = language;
@@ -2,5 +2,9 @@
public interface IBuildingStage public interface IBuildingStage
{ {
/// <summary>
/// Creates a full BotBase instance with all parameters previously set.
/// </summary>
/// <returns></returns>
BotBase Build(); BotBase Build();
} }
@@ -22,6 +22,12 @@ public interface ILanguageSelectionStage
/// <returns></returns> /// <returns></returns>
IBuildingStage UseGerman(); IBuildingStage UseGerman();
/// <summary>
/// Selects persian as the default language for control labels.
/// </summary>
/// <returns></returns>
IBuildingStage UsePersian();
/// <summary> /// <summary>
/// Selects a custom language as the default language for control labels. /// Selects a custom language as the default language for control labels.
/// </summary> /// </summary>
@@ -0,0 +1,86 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using TelegramBotBase.Form;
namespace TelegramBotBase.DependencyInjection
{
public static class Extensions
{
internal static FieldInfo _ServiceProviderField = typeof(FormBase).GetField("_serviceProvider", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
/// <summary>
/// Use Dependency Injection to create new form and inject parameters. (Main variant)
/// </summary>
/// <typeparam name="NewForm"></typeparam>
/// <param name="args"></param>
/// <returns></returns>
public static async Task<NewForm> NavigateTo<NewForm>(this FormBase current_form, params object[] args)
where NewForm : FormBase
{
var _serviceProvider = current_form.GetServiceProvider();
var instance = ActivatorUtilities.CreateInstance(_serviceProvider, typeof(NewForm)) as NewForm;
if (instance == null)
return null; //throw new Exception("Could not instantiate new form via DI.");
instance.SetServiceProvider(_serviceProvider);
await current_form.NavigateTo(instance, args);
return instance;
}
/// <summary>
/// Use Dependency Injection to create new form and inject parameters. (Alternative variant)
/// </summary>
/// <param name="current_form"></param>
/// <param name="formBaseType"></param>
/// <param name="args"></param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public static async Task<FormBase> NavigateTo(this FormBase current_form, Type formBaseType, params object[] args)
{
if (!typeof(FormBase).IsAssignableFrom(formBaseType))
throw new ArgumentException($"{nameof(formBaseType)} argument must be a {nameof(FormBase)} type");
var _serviceProvider = current_form.GetServiceProvider();
var instance = ActivatorUtilities.CreateInstance(_serviceProvider, formBaseType) as FormBase;
if (instance == null)
return null; //throw new Exception("Could not instantiate new form via DI.");
instance.SetServiceProvider(_serviceProvider);
await current_form.NavigateTo(instance, args);
return instance;
}
/// <summary>
/// Sets the internal service provider field.
/// </summary>
/// <param name="form"></param>
/// <param name="serviceProvider"></param>
public static void SetServiceProvider(this FormBase form, IServiceProvider serviceProvider)
{
_ServiceProviderField?.SetValue(form, serviceProvider);
}
/// <summary>
/// Gets the internal service provider field value.
/// </summary>
/// <param name="form"></param>
/// <returns></returns>
public static IServiceProvider GetServiceProvider(this FormBase form)
{
var sp = _ServiceProviderField?.GetValue(form) as IServiceProvider;
return sp;
}
}
}
@@ -12,7 +12,7 @@ public class DefaultStartFormFactory : IStartFormFactory
{ {
if (!typeof(FormBase).IsAssignableFrom(startFormClass)) if (!typeof(FormBase).IsAssignableFrom(startFormClass))
{ {
throw new ArgumentException("startFormClass argument must be a FormBase type"); throw new ArgumentException($"{nameof(startFormClass)} argument must be a {nameof(FormBase)} type");
} }
_startFormClass = startFormClass; _startFormClass = startFormClass;
@@ -1,5 +1,6 @@
using System; using System;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using TelegramBotBase.DependencyInjection;
using TelegramBotBase.Form; using TelegramBotBase.Form;
using TelegramBotBase.Interfaces; using TelegramBotBase.Interfaces;
@@ -14,7 +15,7 @@ public class ServiceProviderStartFormFactory : IStartFormFactory
{ {
if (!typeof(FormBase).IsAssignableFrom(startFormClass)) if (!typeof(FormBase).IsAssignableFrom(startFormClass))
{ {
throw new ArgumentException("startFormClass argument must be a FormBase type"); throw new ArgumentException($"{nameof(startFormClass)} argument must be a {nameof(FormBase)} type");
} }
_startFormClass = startFormClass; _startFormClass = startFormClass;
@@ -23,7 +24,12 @@ public class ServiceProviderStartFormFactory : IStartFormFactory
public FormBase CreateForm() public FormBase CreateForm()
{ {
return (FormBase)ActivatorUtilities.CreateInstance(_serviceProvider, _startFormClass); var fb = (FormBase)ActivatorUtilities.CreateInstance(_serviceProvider, _startFormClass);
//Sets an internal field for future ServiceProvider navigation
fb.SetServiceProvider(_serviceProvider);
return fb;
} }
} }
+1 -1
View File
@@ -1,6 +1,6 @@
namespace TelegramBotBase.Localizations; namespace TelegramBotBase.Localizations;
public class English : Localization public sealed class English : Localization
{ {
public English() public English()
{ {
+1 -1
View File
@@ -1,6 +1,6 @@
namespace TelegramBotBase.Localizations; namespace TelegramBotBase.Localizations;
public class German : Localization public sealed class German : Localization
{ {
public German() public German()
{ {
+37
View File
@@ -0,0 +1,37 @@
namespace TelegramBotBase.Localizations
{
public sealed class Persian : Localization
{
public Persian()
{
Values["Language"] = "فارسی";
Values["ButtonGrid_Title"] = "منو";
Values["ButtonGrid_NoItems"] = "هیچ آیتمی وجود ندارد.";
Values["ButtonGrid_PreviousPage"] = "◀️";
Values["ButtonGrid_NextPage"] = "▶️";
Values["ButtonGrid_CurrentPage"] = "صفحه ی {0} از {1}";
Values["ButtonGrid_SearchFeature"] = "💡 برای فیلتر کردن لیست پیام ارسال کنید. برای بازنشانی فیلتر روی 🔍 کلیک کنید.";
Values["ButtonGrid_Back"] = "بازگشت";
Values["ButtonGrid_CheckAll"] = "بررسی کردن همه";
Values["ButtonGrid_UncheckAll"] = "بررسی نکردن همه";
Values["CalendarPicker_Title"] = "تاریخ را انتخاب کنید";
Values["CalendarPicker_PreviousPage"] = "◀️";
Values["CalendarPicker_NextPage"] = "▶️";
Values["TreeView_Title"] = "گره را انتخاب کنید";
Values["TreeView_LevelUp"] = "🔼 سطح بالا";
Values["ToggleButton_On"] = "روشن";
Values["ToggleButton_Off"] = "خاموش";
Values["ToggleButton_OnIcon"] = "⚫";
Values["ToggleButton_OffIcon"] = "⚪";
Values["ToggleButton_Title"] = "تغییر وضعیت";
Values["ToggleButton_Changed"] = "انتخاب شده";
Values["MultiToggleButton_SelectedIcon"] = "✅";
Values["MultiToggleButton_Title"] = "چند تعویض";
Values["MultiToggleButton_Changed"] = "انتخاب شده";
Values["PromptDialog_Back"] = "بازگشت";
Values["ToggleButton_Changed"] = "تنظیمات تغییر کرد";
Values["ButtonGrid_SearchIcon"] = "🔍";
Values["ButtonGrid_TagIcon"] = "📁";
}
}
}
@@ -72,6 +72,12 @@ public class FormBaseMessageLoop : IMessageLoopFactory
} }
} }
//Message edited ?
if(update.Type == UpdateType.EditedMessage)
{
await activeForm.Edited(mr);
}
//Action Event //Action Event
if (!session.FormSwitched && mr.IsAction) if (!session.FormSwitched && mr.IsAction)
{ {
@@ -65,6 +65,12 @@ public class FullMessageLoop : IMessageLoopFactory
} }
} }
//Message edited ?
if (update.Type == UpdateType.EditedMessage)
{
await activeForm.Edited(mr);
}
//Action Event //Action Event
if (!session.FormSwitched && mr.IsAction) if (!session.FormSwitched && mr.IsAction)
{ {
+1 -1
View File
@@ -29,7 +29,7 @@ public class JsonStateMachine : IStateMachine
if (FallbackStateForm != null && !FallbackStateForm.IsSubclassOf(typeof(FormBase))) if (FallbackStateForm != null && !FallbackStateForm.IsSubclassOf(typeof(FormBase)))
{ {
throw new ArgumentException("FallbackStateForm is not a subclass of FormBase"); throw new ArgumentException($"{nameof(FallbackStateForm)} is not a subclass of {nameof(FormBase)}");
} }
FilePath = file ?? throw new ArgumentNullException(nameof(file)); FilePath = file ?? throw new ArgumentNullException(nameof(file));
@@ -30,7 +30,7 @@ public class SimpleJsonStateMachine : IStateMachine
if (FallbackStateForm != null && !FallbackStateForm.IsSubclassOf(typeof(FormBase))) if (FallbackStateForm != null && !FallbackStateForm.IsSubclassOf(typeof(FormBase)))
{ {
throw new ArgumentException("FallbackStateForm is not a subclass of FormBase"); throw new ArgumentException($"{nameof(FallbackStateForm)} is not a subclass of {nameof(FormBase)}");
} }
FilePath = file ?? throw new ArgumentNullException(nameof(file)); FilePath = file ?? throw new ArgumentNullException(nameof(file));
+1 -1
View File
@@ -27,7 +27,7 @@ public class XmlStateMachine : IStateMachine
if (FallbackStateForm != null && !FallbackStateForm.IsSubclassOf(typeof(FormBase))) if (FallbackStateForm != null && !FallbackStateForm.IsSubclassOf(typeof(FormBase)))
{ {
throw new ArgumentException("FallbackStateForm is not a subclass of FormBase"); throw new ArgumentException($"{nameof(FallbackStateForm)} is not a subclass of {nameof(FormBase)}");
} }
FilePath = file ?? throw new ArgumentNullException(nameof(file)); FilePath = file ?? throw new ArgumentNullException(nameof(file));
+1 -1
View File
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;netcoreapp3.1;net6</TargetFrameworks> <TargetFrameworks>netstandard2.0;netcoreapp3.1;net6;net7</TargetFrameworks>
<LangVersion>10</LangVersion> <LangVersion>10</LangVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild> <GeneratePackageOnBuild>False</GeneratePackageOnBuild>
+8 -1
View File
@@ -30,7 +30,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCoreBot", "Examples\EFCor
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotAndWebApplication", "Examples\BotAndWebApplication\BotAndWebApplication.csproj", "{52EA3201-02E8-46F5-87C4-B4752C8A815C}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotAndWebApplication", "Examples\BotAndWebApplication\BotAndWebApplication.csproj", "{52EA3201-02E8-46F5-87C4-B4752C8A815C}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InlineAndReplyCombination", "Examples\InlineAndReplyCombination\InlineAndReplyCombination.csproj", "{067E8EBE-F90A-4AFF-A0FF-20578216486E}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InlineAndReplyCombination", "Examples\InlineAndReplyCombination\InlineAndReplyCombination.csproj", "{067E8EBE-F90A-4AFF-A0FF-20578216486E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DependencyInjection", "Examples\DependencyInjection\DependencyInjection.csproj", "{689B16BC-200E-4C68-BB2E-8B209070849B}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -78,6 +80,10 @@ Global
{067E8EBE-F90A-4AFF-A0FF-20578216486E}.Debug|Any CPU.Build.0 = Debug|Any CPU {067E8EBE-F90A-4AFF-A0FF-20578216486E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{067E8EBE-F90A-4AFF-A0FF-20578216486E}.Release|Any CPU.ActiveCfg = Release|Any CPU {067E8EBE-F90A-4AFF-A0FF-20578216486E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{067E8EBE-F90A-4AFF-A0FF-20578216486E}.Release|Any CPU.Build.0 = Release|Any CPU {067E8EBE-F90A-4AFF-A0FF-20578216486E}.Release|Any CPU.Build.0 = Release|Any CPU
{689B16BC-200E-4C68-BB2E-8B209070849B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{689B16BC-200E-4C68-BB2E-8B209070849B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{689B16BC-200E-4C68-BB2E-8B209070849B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{689B16BC-200E-4C68-BB2E-8B209070849B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@@ -91,6 +97,7 @@ Global
{261BED47-0404-4A9A-86FC-047DE42A7D25} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5} {261BED47-0404-4A9A-86FC-047DE42A7D25} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5}
{52EA3201-02E8-46F5-87C4-B4752C8A815C} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5} {52EA3201-02E8-46F5-87C4-B4752C8A815C} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5}
{067E8EBE-F90A-4AFF-A0FF-20578216486E} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5} {067E8EBE-F90A-4AFF-A0FF-20578216486E} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5}
{689B16BC-200E-4C68-BB2E-8B209070849B} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {59CB40E1-9FA7-4867-A56F-4F418286F057} SolutionGuid = {59CB40E1-9FA7-4867-A56F-4F418286F057}