diff --git a/PlaylistShared.Pwa/Components/Common/TrackCoverWithPlay.razor b/PlaylistShared.Pwa/Components/Common/TrackCoverWithPlay.razor index 535d610..24ffde5 100644 --- a/PlaylistShared.Pwa/Components/Common/TrackCoverWithPlay.razor +++ b/PlaylistShared.Pwa/Components/Common/TrackCoverWithPlay.razor @@ -7,7 +7,7 @@ - @if (_isHovered || IsCurrentTrackPlaying) + @if (CanPlay && (_isHovered || IsCurrentTrackPlaying)) { @@ -26,6 +26,7 @@ [Parameter] public int Height { get; set; } = 50; [Parameter] public int Width { get; set; } = 50; [Parameter] public string PlaylistShareToken { get; set; } = string.Empty; + [Parameter] public bool CanPlay { get; set; } = false; private bool IsCurrentTrackPlaying => AudioPlayerService.IsPlaying && AudioPlayerService.CurrentTrackId == TrackId; diff --git a/PlaylistShared.Pwa/Components/Common/TrackItem.razor b/PlaylistShared.Pwa/Components/Common/TrackItem.razor index dcaf15f..eaacc8e 100644 --- a/PlaylistShared.Pwa/Components/Common/TrackItem.razor +++ b/PlaylistShared.Pwa/Components/Common/TrackItem.razor @@ -9,6 +9,7 @@ TrackId="@Track.TrackId" TrackTitle="@Track.Title" PlaylistShareToken="@PlaylistShareToken" + CanPlay="@CanPlay" Width="40" Height="40" /> @@ -31,4 +32,5 @@ @code { [Parameter] public YandexTrack Track { get; set; } = null!; [Parameter] public string PlaylistShareToken { get; set; } = string.Empty; + [Parameter] public bool CanPlay { get; set; } = true; } \ No newline at end of file diff --git a/PlaylistShared.Pwa/Components/SharedPlaylist/AddTrackSection.razor b/PlaylistShared.Pwa/Components/SharedPlaylist/AddTrackSection.razor index 5fa8f43..b890ea1 100644 --- a/PlaylistShared.Pwa/Components/SharedPlaylist/AddTrackSection.razor +++ b/PlaylistShared.Pwa/Components/SharedPlaylist/AddTrackSection.razor @@ -29,7 +29,7 @@ - ExistingTrackIds { get; set; } = new(); private string _searchQuery = ""; private bool _isSearching = false; private bool _isFirstSearch = true; private TrackSearchType _searchType = TrackSearchType.All; private List _searchResults = new(); - private HashSet _addingTrackIds = new(); private async Task SearchTracks() { @@ -124,7 +124,7 @@ private async Task ToggleTrack(YandexTrack track) { - if (_addingTrackIds.Contains(track.TrackId)) + if (ExistingTrackIds.Contains(track.TrackId)) { await RemoveTrack(track); } @@ -136,7 +136,7 @@ private async Task RemoveTrack(YandexTrack track) { - if (!_addingTrackIds.Remove(track.TrackId)) return; + if (!ExistingTrackIds.Remove(track.TrackId)) return; try @@ -148,7 +148,7 @@ catch (Exception ex) { Snackbar.Add($"Ошибка добавления: {ex.Message}", Severity.Error); - _addingTrackIds.Add(track.TrackId); + ExistingTrackIds.Add(track.TrackId); } finally { @@ -158,8 +158,8 @@ private async Task AddTrack(YandexTrack track) { - if (_addingTrackIds.Contains(track.TrackId)) return; - _addingTrackIds.Add(track.TrackId); + if (ExistingTrackIds.Contains(track.TrackId)) return; + ExistingTrackIds.Add(track.TrackId); try { @@ -170,7 +170,7 @@ catch (Exception ex) { Snackbar.Add($"Ошибка добавления: {ex.Message}", Severity.Error); - _addingTrackIds.Remove(track.TrackId); + ExistingTrackIds.Remove(track.TrackId); } finally { diff --git a/PlaylistShared.Pwa/Components/SharedPlaylist/PlaylistHeader.razor b/PlaylistShared.Pwa/Components/SharedPlaylist/PlaylistHeader.razor index 4539f0f..d792236 100644 --- a/PlaylistShared.Pwa/Components/SharedPlaylist/PlaylistHeader.razor +++ b/PlaylistShared.Pwa/Components/SharedPlaylist/PlaylistHeader.razor @@ -40,7 +40,6 @@ Size="Size.Medium" /> } - Владелец: @Playlist?.Creator?.UserName diff --git a/PlaylistShared.Pwa/Components/SharedPlaylist/TracksTable.razor b/PlaylistShared.Pwa/Components/SharedPlaylist/TracksTable.razor deleted file mode 100644 index f81683f..0000000 --- a/PlaylistShared.Pwa/Components/SharedPlaylist/TracksTable.razor +++ /dev/null @@ -1,115 +0,0 @@ -@using PlaylistShared.Pwa.Components.Common -@using PlaylistShared.Shared.DTO -@using PlaylistShared.Shared.SharedPlaylist -@inject HttpClient Http -@inject ISnackbar Snackbar -@inject IDialogService DialogService - - - - - - - @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 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 - { - TrackId = t.TrackId, - 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 UpdateTrackListRequest { TrackIds = new List { track.TrackId } }; - 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 class TrackDisplay : YandexTrack - { - public int Index { get; set; } - } -} \ No newline at end of file diff --git a/PlaylistShared.Pwa/Pages/SharedPlaylistView.razor b/PlaylistShared.Pwa/Pages/SharedPlaylistView.razor index 64f8145..b6a6856 100644 --- a/PlaylistShared.Pwa/Pages/SharedPlaylistView.razor +++ b/PlaylistShared.Pwa/Pages/SharedPlaylistView.razor @@ -1,4 +1,5 @@ @page "/shared/{token}" +@using PlaylistShared.Pwa.Components.Common @using PlaylistShared.Pwa.Components.SharedPlaylist @using PlaylistShared.Shared.DTO @using PlaylistShared.Shared.Enums @@ -24,7 +25,6 @@ - @@ -32,12 +32,25 @@ - - + + + + + + + @if (_canRemove) + { + + + + } + + @@ -51,7 +64,7 @@ - + } @@ -64,7 +77,9 @@ @code { [Parameter] public string Token { get; set; } - private TracksTable? _tracksTableRef; + private HashSet _existingTrackIds = new(); + private bool _firstLoadExistingTrackIds; + private List _tracks = new(); private SharedPlaylistDto? _playlist; private bool _loading = true; @@ -90,6 +105,7 @@ _isAuthenticated = authState.User.Identity?.IsAuthenticated == true; _currentUserId = authState.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value; await LoadPlaylist(); + await LoadTracks(); } private async Task ConfigurePermissions() @@ -141,7 +157,6 @@ _playlist = response.Data; await ConfigurePermissions(); - //await LoadTracks(); } else { @@ -162,14 +177,61 @@ private async Task LoadTracks() { if (_playlist == null) return; - if (_tracksTableRef == null) return; _tracksLoading = true; - StateHasChanged(); - await _tracksTableRef.Reload(); + try + { + var response = await Http.GetFromJsonAsync>($"/api/sharedplaylist/{Token}/tracks"); + if (response?.Success == true && response.Data != null) + { + _tracks = response.Data.Tracks; + _existingTrackIds = _tracks.Select(t => t.TrackId).ToHashSet(); + } + else + { + Snackbar.Add(response?.Error?.Message ?? "Не удалось загрузить треки", Severity.Error); + } - _tracksLoading = false; - StateHasChanged(); + } + catch (Exception ex) + { + Snackbar.Add($"Ошибка загрузки треков: {ex.Message}", Severity.Error); + } + finally + { + _tracksLoading = false; + StateHasChanged(); + } + } + + private async Task RemoveTrack(YandexTrack track) + { + var confirmed = await DialogService.ShowMessageBoxAsync( + "Подтверждение удаления", + $"Вы уверены, что хотите удалить трек \"{track.Title}\"?", + yesText: "Удалить", cancelText: "Отмена"); + + if (confirmed != true) return; + + try + { + var request = new UpdateTrackListRequest { TrackIds = new List { track.TrackId } }; + var response = await Http.PostAsJsonAsync($"/api/sharedplaylist/{Token}/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); + } } } \ No newline at end of file