b16627c2b6
- NavMenu: swap 🐢 emoji for <img src="logo.png"> - Login page: swap 🎲 emoji for <img src="logo.png"> - Mini App page: swap 🎲 emoji for <img src="logo.png"> - Replace favicon.png with the new logo - Add logo.png to wwwroot - Update CSS for .nav-brand-icon, .login-logo, .mini-app-logo to use object-fit: contain sizing Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
104 lines
3.5 KiB
Plaintext
104 lines
3.5 KiB
Plaintext
@page "/miniapp"
|
|
@using Microsoft.AspNetCore.Components.Authorization
|
|
@using System.Text.Json.Serialization
|
|
@inject IJSRuntime JS
|
|
@inject NavigationManager Navigation
|
|
|
|
<PageTitle>Mini App Dashboard — GM-Relay</PageTitle>
|
|
|
|
<div class="mini-app-page">
|
|
<div class="mini-app-auth-card" data-auth-status="@miniAppAuthStatus">
|
|
<img src="logo.png" alt="GM-Relay" class="mini-app-logo" />
|
|
<h1>GM-Relay</h1>
|
|
<p>@statusMessage</p>
|
|
|
|
@if (showFallback)
|
|
{
|
|
<a href="/login" class="btn-gm btn-gm-primary">Войти через Telegram</a>
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
@code {
|
|
private string statusMessage = "Открываем dashboard внутри Telegram...";
|
|
private string miniAppAuthStatus = "starting";
|
|
private bool showFallback;
|
|
|
|
[CascadingParameter]
|
|
private Task<AuthenticationState>? AuthStateTask { get; set; }
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
if (AuthStateTask is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var user = (await AuthStateTask).User;
|
|
if (user.Identity?.IsAuthenticated == true)
|
|
{
|
|
Navigation.NavigateTo("/");
|
|
}
|
|
}
|
|
|
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
{
|
|
if (!firstRender)
|
|
{
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
var result = await JS.InvokeAsync<MiniAppAuthResult>(
|
|
"authenticateTelegramMiniApp",
|
|
"/auth/telegram-webapp",
|
|
"/");
|
|
|
|
if (!result.Authenticated)
|
|
{
|
|
miniAppAuthStatus = string.IsNullOrWhiteSpace(result.Reason)
|
|
? "telegram-auth-failed"
|
|
: result.Reason;
|
|
statusMessage = GetStatusMessage(miniAppAuthStatus);
|
|
showFallback = true;
|
|
StateHasChanged();
|
|
await TryWatchLoginAsync();
|
|
}
|
|
}
|
|
catch (JSException)
|
|
{
|
|
miniAppAuthStatus = "telegram-auth-failed";
|
|
statusMessage = "Не удалось получить данные Telegram Mini App. Попробуйте открыть dashboard из бота.";
|
|
showFallback = true;
|
|
StateHasChanged();
|
|
await TryWatchLoginAsync();
|
|
}
|
|
}
|
|
|
|
private async Task TryWatchLoginAsync()
|
|
{
|
|
try
|
|
{
|
|
await JS.InvokeVoidAsync("watchTelegramMiniAppLogin", "/auth/status", "/");
|
|
}
|
|
catch (JSException)
|
|
{
|
|
}
|
|
}
|
|
|
|
private static string GetStatusMessage(string reason) => reason switch
|
|
{
|
|
"telegram-webapp-missing" => "Mini App API не найден. Если страница открыта в браузере, войдите через Telegram.",
|
|
"telegram-init-data-empty" => "Telegram открыл страницу без Mini App initData. Попробуйте войти через Telegram на этом экране.",
|
|
"telegram-auth-failed" => "Не удалось проверить Telegram Mini App. Попробуйте войти через Telegram.",
|
|
_ => "Mini App доступен из Telegram. Для браузера используйте обычный вход."
|
|
};
|
|
|
|
private sealed record MiniAppAuthResult(
|
|
[property: JsonPropertyName("authenticated")] bool Authenticated,
|
|
[property: JsonPropertyName("reason")] string? Reason,
|
|
[property: JsonPropertyName("status")] int? Status,
|
|
[property: JsonPropertyName("redirectUrl")] string? RedirectUrl);
|
|
}
|