Files
PlaylistShared/PlaylistShared.Pwa/Components/Profile/YandexAccount/YandexQrDialog.razor
2026-04-19 21:06:36 +03:00

145 lines
4.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@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();
}
}