@using PlaylistShared.Pwa.Components.Common @using PlaylistShared.Shared.DTO @using PlaylistShared.Shared.Shared @inject HttpClient Http @inject ISnackbar Snackbar @inject IDialogService DialogService # Обложка Название Исполнитель Длительность @if (CanRemove) { } @context.Index @if (!string.IsNullOrEmpty(context.CoverUri)) { @if (CanPlay) { } else { } } @context.Title @string.Join(", ", context.Artists) @FormatDuration(context.DurationMs) @if (CanRemove) { } @code { [Parameter] public string ShareToken { get; set; } = string.Empty; [Parameter] public bool CanPlay { get; set; } [Parameter] public bool CanRemove { get; set; } [Parameter] public string? CurrentPlayingTrackId { get; set; } [Parameter] public bool IsPlaying { get; set; } [Parameter] public EventCallback OnPlayTrack { get; set; } public async Task Reload() { await LoadTracks(); } private List _tracks = new(); private bool _loading = true; protected override async Task OnInitializedAsync() { await LoadTracks(); } private async Task LoadTracks() { _loading = true; try { var response = await Http.GetFromJsonAsync>($"/api/sharedplaylist/{ShareToken}/tracks"); if (response?.Success == true && response.Data != null) { _tracks = response.Data.Tracks.Select((t, idx) => new TrackDisplay { Id = t.Id, Title = t.Title, Artists = t.Artists, DurationMs = t.DurationMs, CoverUri = t.CoverUri, Index = idx + 1 }).ToList(); } else { Snackbar.Add(response?.Error?.Message ?? "Не удалось загрузить треки", Severity.Error); } } catch (Exception ex) { Snackbar.Add($"Ошибка загрузки треков: {ex.Message}", Severity.Error); } finally { _loading = false; StateHasChanged(); } } private async Task RemoveTrack(TrackDisplay track) { var confirmed = await DialogService.ShowMessageBoxAsync( "Подтверждение удаления", $"Вы уверены, что хотите удалить трек \"{track.Title}\"?", yesText: "Удалить", cancelText: "Отмена"); if (confirmed != true) return; try { var request = new RemoveTracksRequest { TrackIds = new List { track.Id } }; var response = await Http.PostAsJsonAsync($"/api/sharedplaylist/{ShareToken}/remove-tracks", request); if (response.IsSuccessStatusCode) { Snackbar.Add("Трек удалён", Severity.Success); await LoadTracks(); } else { var error = await response.Content.ReadFromJsonAsync>(); Snackbar.Add(error?.Error?.Message ?? "Ошибка удаления", Severity.Error); } } catch (Exception ex) { Snackbar.Add($"Ошибка: {ex.Message}", Severity.Error); } } private async Task PlayTrack(string trackId) { await OnPlayTrack.InvokeAsync(trackId); } private string FormatDuration(long ms) { var seconds = ms / 1000; var mins = seconds / 60; var secs = seconds % 60; return $"{mins}:{secs:D2}"; } private class TrackDisplay : YandexTrack { public int Index { get; set; } } }