@page "/shared/{token}" @using PlaylistShared.Shared.DTO @using PlaylistShared.Shared.Enums @using PlaylistShared.Pwa.Services @using PlaylistShared.Shared.Models @inject HttpClient Http @inject ISnackbar Snackbar @inject NavigationManager Navigation @inject AuthenticationStateProvider AuthProvider @inject IDialogService DialogService @if (_loading) { } else if (_playlist == null) { Плейлист не найден или у вас нет доступа } else {
@if (!string.IsNullOrEmpty(_playlist.CoverUrl)) { }
@_playlist.Title Владелец: @_playlist.Creator?.UserName
@if (_isCreator && _isAuthenticated) { Настройки доступа Все Только авторизованные Все Только авторизованные Только добавивший Все Только авторизованные Только добавивший @if (_savingPermissions) { } else { Сохранить } } @if (_canAdd) { Добавить трек @if (_addingTrack) { } else { Добавить } Поддерживаются ссылки вида: https://music.yandex.ru/album/12345/track/67890 }
Треки
@if (_tracksLoading) { } else if (_tracks == null || !_tracks.Any()) { В плейлисте пока нет треков } else { # Обложка Название Исполнитель Длительность @if (_canRemove) { } @context.Index @if (!string.IsNullOrEmpty(context.CoverUri)) { } @context.Title @string.Join(", ", context.Artists) @FormatDuration(context.DurationMs) @if (_canRemove) { } }
}
@code { [Parameter] public string Token { get; set; } private SharedPlaylistDto? _playlist; private bool _loading = true; private bool _isAuthenticated; private bool _isCreator; private bool _canAdd; private bool _canRemove; private UpdatePermissionsDto _editPermissions = new(); private bool _savingPermissions; private string? _currentUserId; private List _tracks = new(); private bool _tracksLoading; private string _trackLink = ""; private bool _addingTrack; protected override async Task OnInitializedAsync() { var authState = await AuthProvider.GetAuthenticationStateAsync(); _isAuthenticated = authState.User.Identity?.IsAuthenticated == true; _currentUserId = authState.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value; await LoadPlaylist(); } private async Task LoadPlaylist() { try { var response = await Http.GetFromJsonAsync>($"/api/sharedplaylist/{Token}"); if (response?.Success == true) { _playlist = response.Data; _isCreator = _playlist.CreatorUserId.ToString() == _currentUserId; _canAdd = _isCreator || _playlist.AddPermission == EditPermission.Everyone || (_playlist.AddPermission == EditPermission.AuthorizedOnly && _isAuthenticated); _canRemove = _isCreator || _playlist.RemovePermission == EditPermission.Everyone || (_playlist.RemovePermission == EditPermission.AuthorizedOnly && _isAuthenticated); if (_isCreator && _isAuthenticated) { _editPermissions = new UpdatePermissionsDto { ViewPermission = _playlist.ViewPermission, AddPermission = _playlist.AddPermission, RemovePermission = _playlist.RemovePermission }; } await LoadTracks(); } else { Snackbar.Add(response?.Error?.Message ?? "Не удалось загрузить плейлист", Severity.Error); } } catch (Exception ex) { Snackbar.Add($"Ошибка: {ex.Message}", Severity.Error); } finally { _loading = false; StateHasChanged(); } } private async Task LoadTracks() { if (_playlist == null) return; _tracksLoading = true; try { var url = $"/api/sharedplaylist/{Token}/tracks"; var response = await Http.GetFromJsonAsync>(url); if (response?.Success == true && response.Data != null) { _tracks = response.Data.Tracks.Select((t, idx) => new YandexTrackDisplay { 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 { _tracksLoading = false; StateHasChanged(); } } private async Task AddTrack() { if (string.IsNullOrWhiteSpace(_trackLink)) { Snackbar.Add("Введите ссылку на трек", Severity.Warning); return; } _addingTrack = true; try { var request = new AddTrackByLinkRequest { Link = _trackLink }; var response = await Http.PostAsJsonAsync($"/api/sharedplaylist/{Token}/add-track-by-link", request); if (response.IsSuccessStatusCode) { Snackbar.Add("Трек успешно добавлен", Severity.Success); _trackLink = ""; 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); } finally { _addingTrack = false; } } private async Task RemoveTrack(YandexTrackDisplay 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/{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); } } private async Task SavePermissions() { if (!_isAuthenticated) return; _savingPermissions = true; try { var response = await Http.PutAsJsonAsync($"/api/sharedplaylist/{Token}/permissions", _editPermissions); if (response.IsSuccessStatusCode) { var result = await response.Content.ReadFromJsonAsync>(); if (result?.Success == true) { _playlist = result.Data; Snackbar.Add("Права доступа обновлены", Severity.Success); _canAdd = _isCreator || _playlist.AddPermission == EditPermission.Everyone || (_playlist.AddPermission == EditPermission.AuthorizedOnly && _isAuthenticated); _canRemove = _isCreator || _playlist.RemovePermission == EditPermission.Everyone || (_playlist.RemovePermission == EditPermission.AuthorizedOnly && _isAuthenticated); } else { Snackbar.Add(result?.Error?.Message ?? "Ошибка обновления", Severity.Error); } } else { Snackbar.Add("Ошибка сохранения прав", Severity.Error); } } catch (Exception ex) { Snackbar.Add($"Ошибка: {ex.Message}", Severity.Error); } finally { _savingPermissions = false; } } private string FormatDuration(int ms) { var seconds = ms / 1000; var mins = seconds / 60; var secs = seconds % 60; return $"{mins}:{secs:D2}"; } private string FormatCoverUrl(string? url, string size = "200x200") { if (string.IsNullOrEmpty(url)) return ""; return "https://" + url.Replace("%%", size); } private class YandexTrackDisplay : YandexTrack { public int Index { get; set; } } }