Добавлен вывод QR яндекса

This commit is contained in:
FrigaT
2026-04-19 21:06:36 +03:00
parent 4324b86512
commit 12241639dc
21 changed files with 1349 additions and 46 deletions

View File

@@ -0,0 +1,145 @@
@using System.Threading
@using PlaylistShared.Shared.DTO
@using PlaylistShared.Shared.Yandex
@inject HttpClient Http
@inject ISnackbar Snackbar
@inject IJSRuntime JsRuntime
<MudDialog>
<TitleContent>
<MudText Typo="Typo.h6">Авторизация Яндекс.Музыки по QR</MudText>
</TitleContent>
<DialogContent>
@if (_qrUrl != null)
{
<div style="text-align: center;">
<MudText Typo="Typo.body2" Class="mb-2">Отсканируйте QR-код приложением Яндекс</MudText>
<MudImage Src="@_qrUrl" Style="max-width: 250px; border-radius: 12px; background-color: white;" />
<MudText Typo="Typo.body2" Class="mt-2" Color="Color.Secondary">
Статус: @_statusText
</MudText>
@if (_isWaiting)
{
<MudProgressCircular Indeterminate Class="mt-2" Size="Size.Small" />
}
@if (_isError)
{
<MudAlert Severity="Severity.Error" Class="mt-4">
@_errorMessage
</MudAlert>
}
</div>
}
else
{
<MudProgressCircular Indeterminate />
}
</DialogContent>
<DialogActions>
<MudButton Variant="Variant.Text" OnClick="Cancel">Отмена</MudButton>
</DialogActions>
</MudDialog>
@code {
[CascadingParameter] IMudDialogInstance MudDialog { get; set; }
private string _qrUrl;
private string _sessionId;
private string _statusText = "Ожидание сканирования";
private bool _isWaiting = true;
private bool _isError = false;
private string _errorMessage = "";
private CancellationTokenSource _cts;
protected override async Task OnInitializedAsync()
{
await StartQrFlow();
}
private async Task StartQrFlow()
{
try
{
// 1. Получить QR и sessionId
var response = await Http.GetFromJsonAsync<ApiResponse<YandexAuthQr>>("/api/yandexaccount/qr");
if (!response.Success || response.Data == null)
{
ShowError("Не удалось получить QR-код");
return;
}
_qrUrl = response.Data.QrLink;
_sessionId = response.Data.SessionId;
// 2. Начать опрос статуса
_cts = new CancellationTokenSource();
_ = PollStatus(_cts.Token);
StateHasChanged();
}
catch (Exception ex)
{
ShowError(ex.Message);
}
}
private async Task PollStatus(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
try
{
await Task.Delay(2000, token);
var statusResponse = await Http.GetFromJsonAsync<ApiResponse<YandexAuthQrCheck>>($"/api/yandexaccount/qr/{_sessionId}", token);
if (statusResponse?.Data != null)
{
switch (statusResponse.Data.Status)
{
case Shared.Enums.YandexAuthQrStatus.Pending:
_statusText = "Ожидание подтверждения...";
break;
case Shared.Enums.YandexAuthQrStatus.Authorized:
_statusText = "Авторизация успешна!";
_isWaiting = false;
Snackbar.Add("Авторизация выполнена", Severity.Success);
MudDialog.Close(DialogResult.Ok(true));
_cts?.Cancel();
return;
case Shared.Enums.YandexAuthQrStatus.Expired:
ShowError("Срок действия QR-кода истёк");
return;
case Shared.Enums.YandexAuthQrStatus.Error:
ShowError("Ошибка авторизации");
return;
}
StateHasChanged();
}
}
catch (TaskCanceledException) { break; }
catch (Exception ex)
{
ShowError(ex.Message);
break;
}
}
}
private void ShowError(string message)
{
_isError = true;
_errorMessage = message;
_isWaiting = false;
StateHasChanged();
}
private void Cancel()
{
_cts?.Cancel();
MudDialog.Close(DialogResult.Cancel());
}
public void Dispose()
{
_cts?.Cancel();
_cts?.Dispose();
}
}

View File

@@ -74,7 +74,7 @@
_tokenErr = false;
var response = await Http.PostAsJsonAsync("/api/yandextoken/set", new SetYandexTokenRequest { Token = token });
var response = await Http.PostAsJsonAsync("/api/yandexaccount/token", new SetYandexTokenRequest { Token = token });
if (response.IsSuccessStatusCode)
{
Snackbar.Add("Токен успешно обновлен", Severity.Success);

View File

@@ -2,7 +2,7 @@
@attribute [Authorize]
@inject HttpClient Http
@inject IDialogService DialogService
@using PlaylistShared.Pwa.Components.Profile
@using PlaylistShared.Pwa.Components.Profile.YandexAccount
@using PlaylistShared.Shared.Profile
<PageTitle>Профиль</PageTitle>
@@ -32,11 +32,15 @@
@_statusText
</MudText>
</MudStack>
<MudButton Variant="Variant.Outlined"
Color="Color.Primary"
OnClick="OpenTokenDialog">
@(_hasToken ? "Переподключить" : "Установить")
</MudButton>
<MudMenu EndIcon="@Icons.Material.Filled.ArrowDropDown"
Label="@(_hasToken ? "Переподключить" : "Подключить")"
Variant="Variant.Outlined"
Dense
Color="Color.Primary">
<MudMenuItem OnClick="OpenTokenDialog">Token</MudMenuItem>
<MudMenuItem OnClick="OpenQrDialog">Qr</MudMenuItem>
</MudMenu>
</MudStack>
</MudCardContent>
</MudCard>
@@ -44,7 +48,7 @@
</MudContainer>
@code {
private string _email = "user@example.com"; // Загрузите из стейта или API
private string _email = "user@example.com";
private string _statusText = "Загрузка...";
private bool _hasToken;
@@ -54,7 +58,7 @@
{
try
{
var response = await Http.GetFromJsonAsync<ApiResponse<YandexTokenStatus>>("/api/yandextoken/status");
var response = await Http.GetFromJsonAsync<ApiResponse<YandexTokenStatus>>("/api/yandexaccount/status");
if (response?.Success == true)
{
_hasToken = response.Data.HasToken;
@@ -72,4 +76,13 @@
if (!result.Canceled) await LoadStatus();
}
private async Task OpenQrDialog()
{
var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small, FullWidth = true };
var dialog = await DialogService.ShowAsync<YandexQrDialog>("", options);
var result = await dialog.Result;
if (!result.Canceled) await LoadStatus();
}
}