This commit is contained in:
25
Demo/Pages/ConfirmPage.cs
Normal file
25
Demo/Pages/ConfirmPage.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using BotPages.Core;
|
||||
using BotPages.Core.Messaging;
|
||||
|
||||
namespace Demo.Pages;
|
||||
|
||||
/// <summary>
|
||||
/// Страница подтверждения заявки.
|
||||
/// </summary>
|
||||
public sealed class ConfirmPage : SingletonPage
|
||||
{
|
||||
public override Task OnEnter(PageContext ctx, CancellationToken ct)
|
||||
=> new MessageBuilder(ctx)
|
||||
.Text("Подтвердите заявку ✅")
|
||||
.Inline("Отправить", "submit")
|
||||
.Inline("Отмена", "cancel")
|
||||
.SendAsync(ct);
|
||||
|
||||
public override Task OnButton(PageContext ctx, string payload, CancellationToken ct)
|
||||
=> payload switch
|
||||
{
|
||||
"submit" => ctx.Navigation.GoToAsync<SubmitPage>(ctx, ct),
|
||||
"cancel" => ctx.Navigation.GoToAsync<WelcomePage>(ctx, ct),
|
||||
_ => Task.CompletedTask
|
||||
};
|
||||
}
|
||||
33
Demo/Pages/DetailsPage.cs
Normal file
33
Demo/Pages/DetailsPage.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using BotPages.Core;
|
||||
using BotPages.Core.Messaging;
|
||||
|
||||
namespace Demo.Pages;
|
||||
|
||||
/// <summary>
|
||||
/// Страница ввода деталей заявки.
|
||||
/// </summary>
|
||||
public sealed class DetailsPage : StatefullPage<DetailsArgs>
|
||||
{
|
||||
public override Task OnEnter(PageContext ctx, DetailsArgs args, CancellationToken ct)
|
||||
=> new MessageBuilder(ctx)
|
||||
.Text($"Заголовок: {args.Title}\nДобавьте детали или нажмите Далее.")
|
||||
.Inline(new InlineButton("Далее", "next"), new InlineButton("Назад", "back"))
|
||||
.Reply("Отмена")
|
||||
.SendAsync(ct);
|
||||
|
||||
public override Task OnButton(PageContext ctx, string payload, CancellationToken ct)
|
||||
=> payload switch
|
||||
{
|
||||
"next" => ctx.Navigation.GoToAsync<FilesPage>(ctx, ct),
|
||||
"back" => ctx.Navigation.GoToAsync<TitlePage>(ctx, ct),
|
||||
_ => Task.CompletedTask
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Аргументы для страницы DetailsPage.
|
||||
/// </summary>
|
||||
public sealed class DetailsArgs
|
||||
{
|
||||
public string Title { get; set; } = "";
|
||||
}
|
||||
29
Demo/Pages/FileSendPage.cs
Normal file
29
Demo/Pages/FileSendPage.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using BotPages.Core;
|
||||
using BotPages.Core.Abstractions;
|
||||
using BotPages.Core.Messaging;
|
||||
|
||||
namespace Demo.Pages;
|
||||
|
||||
public sealed class FileSendPage : SingletonPage
|
||||
{
|
||||
public override Task OnEnter(PageContext ctx, CancellationToken ct)
|
||||
{
|
||||
var content = "Hello from BotPages! This file is generated on the fly.";
|
||||
var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(content));
|
||||
|
||||
var demoFile = new FileDescriptor
|
||||
{
|
||||
Id = "", // не используется при отправке нового файла
|
||||
Name = "demo.txt",
|
||||
Extension = "txt",
|
||||
Size = stream.Length,
|
||||
Kind = FileKind.Document,
|
||||
GetStreamAsync = _ => Task.FromResult<Stream>(stream)
|
||||
};
|
||||
|
||||
return new MessageBuilder(ctx)
|
||||
.Text("Вот пример отправки нового файла 📎", MessageFormat.Markdown)
|
||||
.File(demoFile, "Демонстрационный файл")
|
||||
.SendAsync(ct);
|
||||
}
|
||||
}
|
||||
@@ -1,39 +1,36 @@
|
||||
using BotPages.Core;
|
||||
using BotPages.Core.Abstractions;
|
||||
using BotPages.Core.Messaging;
|
||||
|
||||
namespace Demo.Pages
|
||||
namespace Demo.Pages;
|
||||
|
||||
/// <summary>
|
||||
/// Страница загрузки файлов.
|
||||
/// </summary>
|
||||
public sealed class FilesPage : Page
|
||||
{
|
||||
public sealed class FilesPage : Page
|
||||
public override Task OnEnter(PageContext ctx, CancellationToken ct)
|
||||
=> new MessageBuilder(ctx)
|
||||
.Text("Пришлите файлы для заявки 📎", MessageFormat.Markdown)
|
||||
.Reply("Пропустить")
|
||||
.SendAsync(ct);
|
||||
|
||||
public override async Task OnFile(PageContext ctx, List<FileDescriptor> files, CancellationToken ct)
|
||||
{
|
||||
public static string Id => nameof(FilesPage);
|
||||
|
||||
public override Task<PageResult> EnterAsync(UpdateContext ctx, CancellationToken ct)
|
||||
foreach (var file in files)
|
||||
{
|
||||
var actions = new[]
|
||||
{
|
||||
new PageAction { Label = "⬅️ Назад", Value = "back", Placement = ActionPlacement.Reply, Row = 0 }
|
||||
};
|
||||
|
||||
return Task.FromResult(
|
||||
PageResultBuilder.Empty()
|
||||
.WithText("📂 Здесь можно загрузить или отправить файл.")
|
||||
.WithKeyboard(actions)
|
||||
.Build()
|
||||
);
|
||||
await ctx.SendFileAsync(file, $"Файл '{file.Name}' получен и отправлен обратно.", ct);
|
||||
}
|
||||
|
||||
public override async Task<PageResult> HandleAsync(UpdateContext ctx, CancellationToken ct)
|
||||
{
|
||||
if (ctx.Text == "⬅️ Назад")
|
||||
return PageResultBuilder.Empty().WithNavigate(nameof(MainPage)).Build();
|
||||
|
||||
if (ctx.IncomingFiles?.Count > 0)
|
||||
{
|
||||
await ctx.Client.SendFilesAsync(ctx.Chat.Id, ctx.IncomingFiles, ct);
|
||||
return PageResultBuilder.Empty().WithText("Файл получен и отправлен обратно.").Build();
|
||||
}
|
||||
|
||||
return PageResultBuilder.Empty().WithText("Пришлите файл или нажмите 'Назад'.").Build();
|
||||
}
|
||||
await new MessageBuilder(ctx)
|
||||
.Text($"Получено файлов: {files.Count}", MessageFormat.Plain)
|
||||
.Inline("Далее", "next")
|
||||
.SendAsync(ct);
|
||||
}
|
||||
|
||||
public override Task OnButton(PageContext ctx, string payload, CancellationToken ct)
|
||||
=> ctx.Navigation.GoToAsync<ConfirmPage>(ctx, ct);
|
||||
|
||||
public override Task OnText(PageContext ctx, string text, CancellationToken ct)
|
||||
=> ctx.Navigation.GoToAsync<ConfirmPage>(ctx, ct);
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
using BotPages.Core;
|
||||
|
||||
namespace Demo.Pages
|
||||
{
|
||||
public sealed class InlinePage : Page
|
||||
{
|
||||
public override string Id => nameof(InlinePage);
|
||||
|
||||
public override Task<PageResult> EnterAsync(UpdateContext ctx, CancellationToken ct)
|
||||
{
|
||||
var actions = new[]
|
||||
{
|
||||
new PageAction { Label = "⬅️ Назад", Value = "back", Placement = ActionPlacement.Inline, Row = 0 }
|
||||
};
|
||||
|
||||
return Task.FromResult(
|
||||
PageResultBuilder.Empty()
|
||||
.WithText("Это страница с Inline‑кнопками.")
|
||||
.WithKeyboard(actions)
|
||||
.Build()
|
||||
);
|
||||
}
|
||||
|
||||
public override Task<PageResult> HandleAsync(UpdateContext ctx, CancellationToken ct)
|
||||
{
|
||||
if (ctx.Text == "back")
|
||||
return Task.FromResult(PageResultBuilder.Empty().WithNavigate(nameof(MainPage)).Build());
|
||||
|
||||
return Task.FromResult(PageResultBuilder.Empty().WithText("Нажмите кнопку 'Назад'.").Build());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
using BotPages.Core;
|
||||
|
||||
namespace Demo.Pages
|
||||
{
|
||||
public sealed class MainPage : Page
|
||||
{
|
||||
public override string Id => nameof(MainPage);
|
||||
|
||||
public override Task<PageResult> EnterAsync(UpdateContext ctx, CancellationToken ct)
|
||||
{
|
||||
var actions = new[]
|
||||
{
|
||||
new PageAction(MainPageButtons.Inline) { Placement = ActionPlacement.Reply, Row = 0 },
|
||||
new PageAction(MainPageButtons.Reply) { Placement = ActionPlacement.Reply, Row = 1 },
|
||||
new PageAction(MainPageButtons.Files) { Placement = ActionPlacement.Reply, Row = 2 },
|
||||
};
|
||||
|
||||
return Task.FromResult(
|
||||
PageResultBuilder.Empty()
|
||||
.WithText("🏠 Главная страница.\nВыберите куда перейти:")
|
||||
.WithKeyboard(actions)
|
||||
.Build()
|
||||
);
|
||||
}
|
||||
|
||||
public override Task<PageResult> HandleAsync(UpdateContext ctx, CancellationToken ct)
|
||||
{
|
||||
var button = ActionExtensions.FromActionLabel<MainPageButtons>(ctx.Text);
|
||||
|
||||
return button switch
|
||||
{
|
||||
MainPageButtons.Inline => Task.FromResult(PageResultBuilder.Empty().WithNavigate(nameof(InlinePage)).Build()),
|
||||
MainPageButtons.Reply => Task.FromResult(PageResultBuilder.Empty().WithNavigate(nameof(ReplyPage)).Build()),
|
||||
MainPageButtons.Files => Task.FromResult(PageResultBuilder.Empty().WithNavigate(nameof(FilesPage)).Build()),
|
||||
_ => Task.FromResult(PageResultBuilder.Empty().WithText("Выберите действие с кнопок.").Build())
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public enum MainPageButtons
|
||||
{
|
||||
[Action("📌 Inline")]
|
||||
Inline,
|
||||
|
||||
[Action("⌨️ Reply")]
|
||||
Reply,
|
||||
|
||||
[Action("📂 Файлы")]
|
||||
Files,
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
using BotPages.Core;
|
||||
|
||||
namespace Demo.Pages
|
||||
{
|
||||
public sealed class ReplyPage : Page
|
||||
{
|
||||
public override string Id => nameof(ReplyPage);
|
||||
|
||||
public override Task<PageResult> EnterAsync(UpdateContext ctx, CancellationToken ct)
|
||||
{
|
||||
var actions = new[]
|
||||
{
|
||||
new PageAction { Label = "⬅️ Назад", Value = "back", Placement = ActionPlacement.Reply, Row = 0 }
|
||||
};
|
||||
|
||||
return Task.FromResult(
|
||||
PageResultBuilder.Empty()
|
||||
.WithText("Это страница с Reply‑клавиатурой.")
|
||||
.WithKeyboard(actions)
|
||||
.Build()
|
||||
);
|
||||
}
|
||||
|
||||
public override Task<PageResult> HandleAsync(UpdateContext ctx, CancellationToken ct)
|
||||
{
|
||||
if (ctx.Text == "⬅️ Назад")
|
||||
return Task.FromResult(PageResultBuilder.Empty().WithNavigate(nameof(MainPage)).Build());
|
||||
|
||||
return Task.FromResult(PageResultBuilder.Empty().WithText("Нажмите кнопку 'Назад'.").Build());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
37
Demo/Pages/SubmitPage.cs
Normal file
37
Demo/Pages/SubmitPage.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using BotPages.Core;
|
||||
using BotPages.Core.Messaging;
|
||||
|
||||
namespace Demo.Pages;
|
||||
|
||||
/// <summary>
|
||||
/// Финальная страница отправки заявки.
|
||||
/// </summary>
|
||||
public sealed class SubmitPage : SingletonPage
|
||||
{
|
||||
public override async Task OnEnter(PageContext ctx, CancellationToken ct)
|
||||
{
|
||||
var progress = new MessageBuilder(ctx);
|
||||
|
||||
await progress
|
||||
.Progress("Отправка заявки", 7)
|
||||
.SendAsync(ct);
|
||||
|
||||
int i = 7;
|
||||
do
|
||||
{
|
||||
i += 25;
|
||||
Thread.Sleep(TimeSpan.FromMilliseconds(200));
|
||||
await progress
|
||||
.Progress("Отправка заявки", i)
|
||||
.SendAsync(ct);
|
||||
}
|
||||
while (i < 100);
|
||||
|
||||
await ctx.Navigation.GoToHome(ctx, ct);
|
||||
}
|
||||
|
||||
public override Task OnLeave(PageContext ctx, CancellationToken ct)
|
||||
{
|
||||
return new MessageBuilder(ctx).Text("Заявка отправлена").SendAsync(ct);
|
||||
}
|
||||
}
|
||||
18
Demo/Pages/TitlePage.cs
Normal file
18
Demo/Pages/TitlePage.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using BotPages.Core;
|
||||
using BotPages.Core.Abstractions;
|
||||
using BotPages.Core.Messaging;
|
||||
|
||||
namespace Demo.Pages;
|
||||
/// <summary>
|
||||
/// Страница ввода заголовка заявки.
|
||||
/// </summary>
|
||||
public sealed class TitlePage : SingletonPage
|
||||
{
|
||||
public override Task OnEnter(PageContext ctx, CancellationToken ct)
|
||||
=> new MessageBuilder(ctx)
|
||||
.Text("Введите заголовок заявки:", MessageFormat.Markdown)
|
||||
.SendAsync(ct);
|
||||
|
||||
public override Task OnText(PageContext ctx, string text, CancellationToken ct)
|
||||
=> ctx.Navigation.GoToAsync<DetailsPage, DetailsArgs>(ctx, new DetailsArgs { Title = text }, ct);
|
||||
}
|
||||
56
Demo/Pages/WelcomePage.cs
Normal file
56
Demo/Pages/WelcomePage.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using BotPages.Core;
|
||||
using BotPages.Core.Abstractions;
|
||||
using BotPages.Core.Messaging;
|
||||
|
||||
namespace Demo.Pages;
|
||||
|
||||
/// <summary>
|
||||
/// Стартовая страница демо‑бота.
|
||||
/// </summary>
|
||||
public sealed class WelcomePage : SingletonPage
|
||||
{
|
||||
public override Task OnEnter(PageContext ctx, CancellationToken ct)
|
||||
=> new MessageBuilder(ctx)
|
||||
.Text("Добро пожаловать! 🚀")
|
||||
.Reply(WelcomePageButtons.CreateRequest)
|
||||
.Reply(WelcomePageButtons.Help)
|
||||
.Reply(WelcomePageButtons.SendFile)
|
||||
.SendAsync(ct);
|
||||
|
||||
public override Task OnText(PageContext ctx, string text, CancellationToken ct)
|
||||
{
|
||||
var button = ButtonExtensions.FromButtonLabel<WelcomePageButtons>(text);
|
||||
|
||||
switch (button)
|
||||
{
|
||||
case WelcomePageButtons.CreateRequest:
|
||||
{
|
||||
return ctx.Navigation.GoToAsync<TitlePage>(ctx, ct);
|
||||
}
|
||||
|
||||
case WelcomePageButtons.Help:
|
||||
{
|
||||
return new MessageBuilder(ctx).Text("Здесь будет справка.", MessageFormat.Plain).SendAsync(ct);
|
||||
}
|
||||
|
||||
case WelcomePageButtons.SendFile:
|
||||
{
|
||||
return ctx.Navigation.GoToAsync<FileSendPage>(ctx, ct);
|
||||
}
|
||||
}
|
||||
|
||||
return base.OnText(ctx, text, ct);
|
||||
}
|
||||
}
|
||||
|
||||
public enum WelcomePageButtons
|
||||
{
|
||||
[Button("Создать заявку")]
|
||||
CreateRequest,
|
||||
|
||||
[Button("Помощь")]
|
||||
Help,
|
||||
|
||||
[Button("Отправка файла")]
|
||||
SendFile,
|
||||
}
|
||||
Reference in New Issue
Block a user