243 lines
8.8 KiB
Plaintext
243 lines
8.8 KiB
Plaintext
@page "/shared/{token}"
|
||
@using PlaylistShared.Pwa.Components.Common
|
||
@using PlaylistShared.Pwa.Components.SharedPlaylist
|
||
@using PlaylistShared.Shared.DTO
|
||
@using PlaylistShared.Shared.Enums
|
||
@using PlaylistShared.Pwa.Services
|
||
@using PlaylistShared.Shared.SharedPlaylist
|
||
@inject HttpClient Http
|
||
@inject ISnackbar Snackbar
|
||
@inject NavigationManager Navigation
|
||
@inject AuthenticationStateProvider AuthProvider
|
||
@inject IDialogService DialogService
|
||
|
||
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pa-4" Style="height: 100%;">
|
||
@if (_loading)
|
||
{
|
||
<MudProgressCircular Indeterminate />
|
||
}
|
||
else if (_playlist == null)
|
||
{
|
||
<MudAlert Severity="Severity.Error">Плейлист не найден или у вас нет доступа</MudAlert>
|
||
}
|
||
else
|
||
{
|
||
<MudSplitPanel Class="flex-grow-1" Style="height: 100%;">
|
||
<FirstPanel>
|
||
<MudCard Class="d-flex flex-column" Style="height: 100%;">
|
||
<MudCardHeader>
|
||
<CardHeaderContent>
|
||
<PlaylistHeader Playlist="@_playlist" />
|
||
</CardHeaderContent>
|
||
</MudCardHeader>
|
||
|
||
<MudCardContent Class="flex-grow-1 d-flex flex-column" Style="overflow: hidden;">
|
||
<MudItem>
|
||
<MudIconButton Icon="@Icons.Material.Filled.Refresh" OnClick="LoadTracks" Disabled="@_tracksLoading" Size="Size.Medium" />
|
||
</MudItem>
|
||
|
||
<MudTable Items="@_tracks"
|
||
Virtualize
|
||
Hover
|
||
Elevation="0"
|
||
Class="d-flex flex-grow-1 flex-column"
|
||
Style="min-height: 0;"
|
||
Breakpoint="Breakpoint.Sm"
|
||
Loading="@_tracksLoading">
|
||
<RowTemplate>
|
||
<MudTd Style="width: 100%;">
|
||
<TrackItem Track="@context" PlaylistShareToken="Token" CanPlay="@_canPlay" />
|
||
</MudTd>
|
||
@if (_canRemove)
|
||
{
|
||
<MudTd>
|
||
<MudIconButton Icon="@Icons.Material.Filled.Delete" Color="Color.Error" OnClick="() => RemoveTrack(context)" />
|
||
</MudTd>
|
||
}
|
||
</RowTemplate>
|
||
</MudTable>
|
||
</MudCardContent>
|
||
</MudCard>
|
||
</FirstPanel>
|
||
<SecondPanel>
|
||
@if (_canAdd)
|
||
{
|
||
<MudCard Class="d-flex flex-column" Style="height: 100%;">
|
||
<MudCardHeader>
|
||
<CardHeaderContent>
|
||
<MudText Typo="Typo.h5" Color="Color.Primary">Добавление треков</MudText>
|
||
</CardHeaderContent>
|
||
</MudCardHeader>
|
||
|
||
<MudCardContent Class="flex-grow-1 d-flex flex-column" Style="overflow: hidden;">
|
||
<AddTrackSection ShareToken="Token" OnTrackAdded="LoadTracks" OnTrackRemoved="LoadTracks" ExistingTrackIds="_existingTrackIds" />
|
||
</MudCardContent>
|
||
</MudCard>
|
||
}
|
||
</SecondPanel>
|
||
</MudSplitPanel>
|
||
}
|
||
</MudContainer>
|
||
|
||
|
||
@code {
|
||
[Parameter] public string Token { get; set; }
|
||
|
||
private HashSet<string> _existingTrackIds = new();
|
||
private bool _firstLoadExistingTrackIds;
|
||
private List<YandexTrack> _tracks = new();
|
||
|
||
private SharedPlaylistDto? _playlist;
|
||
private bool _loading = true;
|
||
private bool _isAuthenticated;
|
||
private bool _isCreator;
|
||
private bool _canPlay;
|
||
private bool _canAdd;
|
||
private bool _canRemove;
|
||
private UpdatePermissionsDto _editPermissions = new();
|
||
private bool _savingPermissions;
|
||
private string? _currentUserId;
|
||
|
||
private bool _isFavorite = false;
|
||
private bool _favoriteLoading = false;
|
||
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();
|
||
await LoadTracks();
|
||
}
|
||
|
||
private async Task ConfigurePermissions()
|
||
{
|
||
if (_playlist is null)
|
||
{
|
||
_isCreator = false;
|
||
_canAdd = false;
|
||
_canRemove = false;
|
||
_canPlay = false;
|
||
}
|
||
else
|
||
{
|
||
_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);
|
||
|
||
_canPlay = _isCreator
|
||
|| _playlist.PlayPermission == ViewPermission.Everyone
|
||
|| (_playlist.PlayPermission == ViewPermission.AuthorizedOnly && _isAuthenticated);
|
||
|
||
if (_isCreator && _isAuthenticated)
|
||
{
|
||
_editPermissions = new UpdatePermissionsDto
|
||
{
|
||
ViewPermission = _playlist.ViewPermission,
|
||
AddPermission = _playlist.AddPermission,
|
||
RemovePermission = _playlist.RemovePermission,
|
||
PlayPermission = _playlist.PlayPermission,
|
||
};
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
private async Task LoadPlaylist()
|
||
{
|
||
try
|
||
{
|
||
var response = await Http.GetFromJsonAsync<ApiResponse<SharedPlaylistDto>>($"/api/sharedplaylist/{Token}");
|
||
if (response?.Success == true)
|
||
{
|
||
_playlist = response.Data;
|
||
|
||
await ConfigurePermissions();
|
||
}
|
||
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 response = await Http.GetFromJsonAsync<ApiResponse<YandexPlaylistData>>($"/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);
|
||
}
|
||
|
||
}
|
||
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<string> { 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<ApiResponse<object>>();
|
||
Snackbar.Add(error?.Error?.Message ?? "Ошибка удаления", Severity.Error);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Snackbar.Add($"Ошибка: {ex.Message}", Severity.Error);
|
||
}
|
||
}
|
||
} |