Files
PlaylistShared/PlaylistShared.Pwa/Components/SharedPlaylist/TracksTable.razor

156 lines
5.3 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 PlaylistShared.Pwa.Components.Common
@using PlaylistShared.Shared.DTO
@using PlaylistShared.Shared.Shared
@inject HttpClient Http
@inject ISnackbar Snackbar
@inject IDialogService DialogService
<MudTable Items="@_tracks" Hover="true" Breakpoint="Breakpoint.Sm" Loading="_loading">
<HeaderContent>
<MudTh>#</MudTh>
<MudTh>Обложка</MudTh>
<MudTh>Название</MudTh>
<MudTh>Исполнитель</MudTh>
<MudTh>Длительность</MudTh>
@if (CanRemove)
{
<MudTh></MudTh>
}
</HeaderContent>
<RowTemplate>
<MudTd DataLabel="#" Style="font-weight: normal;">@context.Index</MudTd>
<MudTd DataLabel="Обложка">
@if (!string.IsNullOrEmpty(context.CoverUri))
{
@if (CanPlay)
{
<TrackCoverWithPlay CoverUrl="@context.CoverUri"
TrackId="@context.Id"
Width="50" Height="50"/>
}
else
{
<MudImage Src="@context.CoverUri.FormatCoverUrl(50, 50)" Height="50" Width="50" Class="rounded" />
}
}
</MudTd>
<MudTd DataLabel="Название">
<MudLink Href="@($"https://music.yandex.ru/track/{context.Id}")" Target="_blank" Underline="Underline.Hover">
@context.Title
<MudIcon Icon="@Icons.Material.Filled.OpenInNew" Size="Size.Small" Class="ml-1" />
</MudLink>
</MudTd>
<MudTd DataLabel="Исполнитель">@string.Join(", ", context.Artists)</MudTd>
<MudTd DataLabel="Длительность">@FormatDuration(context.DurationMs)</MudTd>
@if (CanRemove)
{
<MudTd DataLabel="">
<MudIconButton Icon="@Icons.Material.Filled.Delete" Color="Color.Error" OnClick="() => RemoveTrack(context)" />
</MudTd>
}
</RowTemplate>
</MudTable>
@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<string> OnPlayTrack { get; set; }
public async Task Reload()
{
await LoadTracks();
}
private List<TrackDisplay> _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<ApiResponse<YandexPlaylistData>>($"/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<string> { 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<ApiResponse<object>>();
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; }
}
}