Изменено отображение треков
This commit is contained in:
@@ -66,7 +66,6 @@
|
|||||||
}
|
}
|
||||||
_shareUrl = ShareUrl;
|
_shareUrl = ShareUrl;
|
||||||
_popoverOpen = true;
|
_popoverOpen = true;
|
||||||
await CopyLink();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
@using Microsoft.AspNetCore.Components.Web
|
@using Microsoft.AspNetCore.Components.Web
|
||||||
@inject IAudioPlayerService AudioPlayerService
|
@inject IAudioPlayerService AudioPlayerService
|
||||||
|
|
||||||
<MudPaper Elevation="0"
|
<MudItem @onmouseenter="HandleMouseEnter"
|
||||||
@onmouseenter="HandleMouseEnter"
|
|
||||||
@onmouseleave="HandleMouseLeave"
|
@onmouseleave="HandleMouseLeave"
|
||||||
style="position: relative; display: inline-block; cursor: pointer; border-radius: 4px; overflow: hidden;">
|
style="position: relative; display: inline-block; cursor: pointer; border-radius: 4px; overflow: hidden;">
|
||||||
|
|
||||||
@@ -10,15 +9,15 @@
|
|||||||
|
|
||||||
@if (_isHovered || IsCurrentTrackPlaying)
|
@if (_isHovered || IsCurrentTrackPlaying)
|
||||||
{
|
{
|
||||||
<MudPaper class="play-overlay"
|
<MudItem class="play-overlay"
|
||||||
style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.6); display: flex; align-items: center; justify-content: center; border-radius: 4px;">
|
style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.6); display: flex; align-items: center; justify-content: center; border-radius: 4px;">
|
||||||
<MudIconButton Icon="@(IsCurrentTrackPlaying? Icons.Material.Filled.Pause : Icons.Material.Filled.PlayArrow)"
|
<MudIconButton Icon="@(IsCurrentTrackPlaying? Icons.Material.Filled.Pause : Icons.Material.Filled.PlayArrow)"
|
||||||
Color="Color.Inherit"
|
Color="Color.Inherit"
|
||||||
Size="Size.Large"
|
Size="Size.Large"
|
||||||
OnClick="OnPlayClick" />
|
OnClick="OnPlayClick" />
|
||||||
</MudPaper>
|
</MudItem>
|
||||||
}
|
}
|
||||||
</MudPaper>
|
</MudItem>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter] public string CoverUrl { get; set; } = string.Empty;
|
[Parameter] public string CoverUrl { get; set; } = string.Empty;
|
||||||
|
|||||||
34
PlaylistShared.Pwa/Components/Common/TrackItem.razor
Normal file
34
PlaylistShared.Pwa/Components/Common/TrackItem.razor
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
@using PlaylistShared.Shared.DTO
|
||||||
|
@using PlaylistShared.Pwa.Components.Common
|
||||||
|
@using PlaylistShared.Pwa.Extensions
|
||||||
|
|
||||||
|
<MudStack Row AlignItems="AlignItems.Center">
|
||||||
|
<!-- Обложка с фиксированной шириной -->
|
||||||
|
<MudItem>
|
||||||
|
<TrackCoverWithPlay CoverUrl="@Track.CoverUri"
|
||||||
|
TrackId="@Track.TrackId"
|
||||||
|
TrackTitle="@Track.Title"
|
||||||
|
PlaylistShareToken="@PlaylistShareToken"
|
||||||
|
Width="40" Height="40" />
|
||||||
|
</MudItem>
|
||||||
|
|
||||||
|
<!-- Информация о треке (занимает всё доступное место) -->
|
||||||
|
<MudItem>
|
||||||
|
<MudStack Spacing="0">
|
||||||
|
<MudText Typo="Typo.body1" Color="Color.Secondary">@Track.Title</MudText>
|
||||||
|
<MudText Typo="Typo.body2" >@string.Join(", ", Track.Artists)</MudText>
|
||||||
|
</MudStack>
|
||||||
|
</MudItem>
|
||||||
|
|
||||||
|
<MudSpacer />
|
||||||
|
|
||||||
|
<!-- Длительность (фиксированная ширина по содержимому) -->
|
||||||
|
<MudItem>
|
||||||
|
<MudText Typo="Typo.body2">@Track.DurationMs.FormatDuration()</MudText>
|
||||||
|
</MudItem>
|
||||||
|
</MudStack>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter] public YandexTrack Track { get; set; } = null!;
|
||||||
|
[Parameter] public string PlaylistShareToken { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
@using PlaylistShared.Pwa.Components.Common
|
|
||||||
@using PlaylistShared.Shared.DTO
|
|
||||||
@inject HttpClient Http
|
|
||||||
@inject ISnackbar Snackbar
|
|
||||||
|
|
||||||
<MudStack AlignItems="AlignItems.Center">
|
|
||||||
<MudTextField @bind-Value="_searchQuery"
|
|
||||||
Label="Название трека или исполнитель"
|
|
||||||
Variant="Variant.Outlined"
|
|
||||||
Disabled="@_isSearching"
|
|
||||||
FullWidth="true"
|
|
||||||
OnKeyUp="@(async (e) => { if (e.Key == "Enter") await SearchTracks(); })"
|
|
||||||
Adornment="Adornment.End" AdornmentIcon="@Icons.Material.Filled.Search" AdornmentColor="Color.Secondary"
|
|
||||||
/>
|
|
||||||
|
|
||||||
@if (_isSearching)
|
|
||||||
{
|
|
||||||
<MudProgressLinear Color="Color.Primary" Indeterminate="true" Class="my-7" />
|
|
||||||
}
|
|
||||||
else if (_searchResults.Any())
|
|
||||||
{
|
|
||||||
<div style="max-height: 400px; overflow-y: auto;">
|
|
||||||
@foreach (var track in _searchResults)
|
|
||||||
{
|
|
||||||
<div style="display: flex; align-items: center; gap: 12px; padding: 8px; border-bottom: 1px solid rgba(0,0,0,0.1);">
|
|
||||||
<div style="width: 40px; height: 40px; flex-shrink: 0;">
|
|
||||||
<TrackCoverWithPlay CoverUrl="@track.CoverUri"
|
|
||||||
TrackId="@track.TrackId"
|
|
||||||
TrackTitle="@track.Title"
|
|
||||||
PlaylistShareToken="@ShareToken"
|
|
||||||
Width="40" Height="40"/>
|
|
||||||
</div>
|
|
||||||
<div style="flex: 1; min-width: 0;">
|
|
||||||
<MudText Typo="Typo.body1" Style="font-weight: 500;">@track.Title</MudText>
|
|
||||||
<MudText Typo="Typo.body2" Color="Color.Secondary">@string.Join(", ", track.Artists)</MudText>
|
|
||||||
</div>
|
|
||||||
<div style="flex-shrink: 0;">
|
|
||||||
<MudText Typo="Typo.body2">@track.DurationMs.FormatDuration()</MudText>
|
|
||||||
</div>
|
|
||||||
<div style="flex-shrink: 0;">
|
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.AddCircle"
|
|
||||||
Color="Color.Primary"
|
|
||||||
OnClick="() => AddTrack(track)"
|
|
||||||
Disabled="_addingTrackIds.Contains(track.TrackId)"
|
|
||||||
Title="Добавить в плейлист" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
else if (!_isFirstSearch)
|
|
||||||
{
|
|
||||||
<MudAlert Severity="Severity.Info">Ничего не найдено. Попробуйте изменить запрос.</MudAlert>
|
|
||||||
}
|
|
||||||
</MudStack>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter] public EventCallback<string> OnAddTrack { get; set; }
|
|
||||||
[Parameter] public string ShareToken { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
private List<YandexTrack> _searchResults = new();
|
|
||||||
private bool _isSearching;
|
|
||||||
private bool _isFirstSearch = true;
|
|
||||||
private HashSet<string> _addingTrackIds = new();
|
|
||||||
private string _searchQuery = string.Empty;
|
|
||||||
|
|
||||||
private async Task SearchTracks()
|
|
||||||
{
|
|
||||||
_isFirstSearch = false;
|
|
||||||
_isSearching = true;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var url = $"/api/yandexsearch/query?query={Uri.EscapeDataString(_searchQuery)}&limit=20";
|
|
||||||
if (!string.IsNullOrEmpty(ShareToken))
|
|
||||||
url += $"&shared_id={Uri.EscapeDataString(ShareToken)}";
|
|
||||||
|
|
||||||
var response = await Http.GetFromJsonAsync<ApiResponse<List<YandexTrack>>>(url);
|
|
||||||
if (response?.Success == true)
|
|
||||||
_searchResults = response.Data ?? new();
|
|
||||||
else
|
|
||||||
Snackbar.Add(response?.Error?.Message ?? "Ошибка поиска", Severity.Error);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Snackbar.Add($"Ошибка: {ex.Message}", Severity.Error);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_isSearching = false;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task AddTrack(YandexTrack track)
|
|
||||||
{
|
|
||||||
if (_addingTrackIds.Contains(track.TrackId)) return;
|
|
||||||
_addingTrackIds.Add(track.TrackId);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await OnAddTrack.InvokeAsync(track.TrackId);
|
|
||||||
Snackbar.Add($"Трек \"{track.Title}\" добавлен", Severity.Success);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Snackbar.Add($"Ошибка добавления: {ex.Message}", Severity.Error);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_addingTrackIds.Remove(track.TrackId);
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,72 +5,50 @@
|
|||||||
@inject HttpClient Http
|
@inject HttpClient Http
|
||||||
@inject ISnackbar Snackbar
|
@inject ISnackbar Snackbar
|
||||||
|
|
||||||
<MudPaper Class="mb-4" Elevation="0" Style="background-color: rgba(0,0,0,0.05); border-radius: 8px;">
|
<MudStack AlignItems="AlignItems.Stretch">
|
||||||
<MudStack AlignItems="AlignItems.Start">
|
<MudTextField @bind-Value="_searchQuery"
|
||||||
<MudTextField @bind-Value="_searchQuery"
|
@bind-Value:after="SearchTracks"
|
||||||
@bind-Value:after="SearchTracks"
|
Variant="Variant.Outlined"
|
||||||
Variant="Variant.Outlined"
|
FullWidth
|
||||||
FullWidth
|
Label="Название или ссылка на трек Яндекс.Музыки"
|
||||||
Label="Название или ссылка на трек Яндекс.Музыки"
|
Disabled="@_isSearching"
|
||||||
Disabled="@_isSearching"
|
Adornment="Adornment.End" AdornmentIcon="@Icons.Material.Filled.Search" AdornmentColor="Color.Secondary"
|
||||||
Adornment="Adornment.End" AdornmentIcon="@Icons.Material.Filled.Search" AdornmentColor="Color.Secondary"
|
/>
|
||||||
/>
|
|
||||||
|
|
||||||
<MudToggleGroup T="TrackSearchType"
|
<MudToggleGroup T="TrackSearchType"
|
||||||
@bind-Value="_searchType"
|
@bind-Value="_searchType"
|
||||||
@bind-Value:after="SearchTracks"
|
@bind-Value:after="SearchTracks"
|
||||||
Size="Size.Small"
|
Size="Size.Small"
|
||||||
Color="Color.Primary"
|
Color="Color.Primary"
|
||||||
Disabled="@(_isSearching)"
|
Disabled="@(_isSearching)"
|
||||||
>
|
>
|
||||||
<MudToggleItem Value="TrackSearchType.All" Text="Все" />
|
<MudToggleItem Value="TrackSearchType.All" Text="Все" />
|
||||||
<MudToggleItem Value="TrackSearchType.Track" Text="Трек" />
|
<MudToggleItem Value="TrackSearchType.Track" Text="Трек" />
|
||||||
<MudToggleItem Value="TrackSearchType.Album" Text="Альбом" />
|
<MudToggleItem Value="TrackSearchType.Album" Text="Альбом" />
|
||||||
<MudToggleItem Value="TrackSearchType.Artist" Text="Исполнитель" />
|
<MudToggleItem Value="TrackSearchType.Artist" Text="Исполнитель" />
|
||||||
</MudToggleGroup>
|
</MudToggleGroup>
|
||||||
|
|
||||||
@if (_isSearching)
|
<MudTable Items="@_searchResults"
|
||||||
{
|
Virtualize="@true"
|
||||||
<MudProgressLinear Color="Color.Primary" Indeterminate="true" Class="my-7" />
|
Height="400px"
|
||||||
}
|
Hover="true"
|
||||||
else if (_searchResults.Any())
|
Breakpoint="Breakpoint.Sm"
|
||||||
{
|
Loading="@_isSearching">
|
||||||
<div style="max-height: 400px; overflow-y: auto;">
|
<RowTemplate>
|
||||||
@foreach (var track in _searchResults)
|
<MudTd Style="width: 100%;">
|
||||||
{
|
<TrackItem Track="@context" PlaylistShareToken="@ShareToken" />
|
||||||
<div style="display: flex; align-items: center; gap: 12px; padding: 8px; border-bottom: 1px solid rgba(0,0,0,0.1);">
|
</MudTd>
|
||||||
<div style="width: 40px; height: 40px; flex-shrink: 0;">
|
<MudTd>
|
||||||
<TrackCoverWithPlay CoverUrl="@track.CoverUri"
|
<MudToggleIconButton Toggled="_addingTrackIds.Contains(context.TrackId)"
|
||||||
TrackId="@track.TrackId"
|
Icon="@Icons.Material.Filled.AddCircle"
|
||||||
TrackTitle="@track.Title"
|
Color="@Color.Primary"
|
||||||
PlaylistShareToken="@ShareToken"
|
ToggledIcon="@Icons.Material.Filled.RemoveCircle"
|
||||||
Width="40" Height="40" />
|
ToggledColor="@Color.Error"
|
||||||
</div>
|
ToggledChanged="() => ToggleTrack(context)" />
|
||||||
<div style="flex: 1; min-width: 0;">
|
</MudTd>
|
||||||
<MudText Typo="Typo.body1" Style="font-weight: 500;">@track.Title</MudText>
|
</RowTemplate>
|
||||||
<MudText Typo="Typo.body2" Color="Color.Secondary">@string.Join(", ", track.Artists)</MudText>
|
</MudTable>
|
||||||
</div>
|
</MudStack>
|
||||||
<div style="flex-shrink: 0;">
|
|
||||||
<MudText Typo="Typo.body2">@track.DurationMs.FormatDuration()</MudText>
|
|
||||||
</div>
|
|
||||||
<div style="flex-shrink: 0;">
|
|
||||||
<MudToggleIconButton Toggled="_addingTrackIds.Contains(track.TrackId)"
|
|
||||||
Icon="@Icons.Material.Filled.AddCircle"
|
|
||||||
Color="@Color.Primary"
|
|
||||||
ToggledIcon="@Icons.Material.Filled.RemoveCircle"
|
|
||||||
ToggledColor="@Color.Error"
|
|
||||||
ToggledChanged="() => ToggleTrack(track)" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
else if (!_isFirstSearch)
|
|
||||||
{
|
|
||||||
<MudAlert Severity="Severity.Info">Ничего не найдено. Попробуйте изменить запрос.</MudAlert>
|
|
||||||
}
|
|
||||||
</MudStack>
|
|
||||||
</MudPaper>
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter] public string ShareToken { get; set; } = string.Empty;
|
[Parameter] public string ShareToken { get; set; } = string.Empty;
|
||||||
@@ -165,7 +143,7 @@
|
|||||||
{
|
{
|
||||||
await RemoveTrackById(track.TrackId);
|
await RemoveTrackById(track.TrackId);
|
||||||
await OnTrackRemoved.InvokeAsync();
|
await OnTrackRemoved.InvokeAsync();
|
||||||
Snackbar.Add($"Трек \"{track.Title}\" добавлен", Severity.Success);
|
Snackbar.Add($"Трек \"{track.Title}\" удален", Severity.Success);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -208,7 +186,6 @@
|
|||||||
var response = await Http.PostAsJsonAsync($"/api/sharedplaylist/{ShareToken}/add-tracks", request);
|
var response = await Http.PostAsJsonAsync($"/api/sharedplaylist/{ShareToken}/add-tracks", request);
|
||||||
if (response.IsSuccessStatusCode)
|
if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
Snackbar.Add("Трек успешно добавлен", Severity.Success);
|
|
||||||
await OnTrackAdded.InvokeAsync(); // уведомляем родителя, что список треков изменился
|
await OnTrackAdded.InvokeAsync(); // уведомляем родителя, что список треков изменился
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -235,7 +212,6 @@
|
|||||||
var response = await Http.PostAsJsonAsync($"/api/sharedplaylist/{ShareToken}/remove-tracks", request);
|
var response = await Http.PostAsJsonAsync($"/api/sharedplaylist/{ShareToken}/remove-tracks", request);
|
||||||
if (response.IsSuccessStatusCode)
|
if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
Snackbar.Add("Трек успешно удален", Severity.Success);
|
|
||||||
await OnTrackAdded.InvokeAsync(); // уведомляем родителя, что список треков изменился
|
await OnTrackAdded.InvokeAsync(); // уведомляем родителя, что список треков изменился
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -5,48 +5,14 @@
|
|||||||
@inject ISnackbar Snackbar
|
@inject ISnackbar Snackbar
|
||||||
@inject IDialogService DialogService
|
@inject IDialogService DialogService
|
||||||
|
|
||||||
<MudTable Items="@_tracks" Hover="true" Breakpoint="Breakpoint.Sm" Loading="_loading">
|
<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>
|
<RowTemplate>
|
||||||
<MudTd DataLabel="#" Style="font-weight: normal;">@context.Index</MudTd>
|
<MudTd Style="width: 100%;">
|
||||||
<MudTd DataLabel="Обложка">
|
<TrackItem Track="@context" PlaylistShareToken="@ShareToken" />
|
||||||
@if (!string.IsNullOrEmpty(context.CoverUri))
|
|
||||||
{
|
|
||||||
@if (CanPlay)
|
|
||||||
{
|
|
||||||
<TrackCoverWithPlay CoverUrl="@context.CoverUri"
|
|
||||||
TrackId="@context.TrackId"
|
|
||||||
TrackTitle="@context.Title"
|
|
||||||
PlaylistShareToken="@ShareToken"
|
|
||||||
Width="50" Height="50"/>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<MudImage Src="@context.CoverUri.FormatCoverUrl(50, 50)" Height="50" Width="50" Class="rounded" />
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</MudTd>
|
</MudTd>
|
||||||
<MudTd DataLabel="Название">
|
|
||||||
<MudLink Href="@($"https://music.yandex.ru/track/{context.TrackId}")" 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="Длительность">@context.DurationMs.FormatDuration()</MudTd>
|
|
||||||
@if (CanRemove)
|
@if (CanRemove)
|
||||||
{
|
{
|
||||||
<MudTd DataLabel="">
|
<MudTd>
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.Delete" Color="Color.Error" OnClick="() => RemoveTrack(context)" />
|
<MudIconButton Icon="@Icons.Material.Filled.Delete" Color="Color.Error" OnClick="() => RemoveTrack(context)" />
|
||||||
</MudTd>
|
</MudTd>
|
||||||
}
|
}
|
||||||
@@ -57,7 +23,6 @@
|
|||||||
[Parameter] public string ShareToken { get; set; } = string.Empty;
|
[Parameter] public string ShareToken { get; set; } = string.Empty;
|
||||||
[Parameter] public bool CanPlay { get; set; }
|
[Parameter] public bool CanPlay { get; set; }
|
||||||
[Parameter] public bool CanRemove { get; set; }
|
[Parameter] public bool CanRemove { get; set; }
|
||||||
[Parameter] public string? CurrentPlayingTrackId { get; set; }
|
|
||||||
[Parameter] public bool IsPlaying { get; set; }
|
[Parameter] public bool IsPlaying { get; set; }
|
||||||
[Parameter] public EventCallback<string> OnPlayTrack { get; set; }
|
[Parameter] public EventCallback<string> OnPlayTrack { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
@inject AuthenticationStateProvider AuthProvider
|
@inject AuthenticationStateProvider AuthProvider
|
||||||
@inject IDialogService DialogService
|
@inject IDialogService DialogService
|
||||||
|
|
||||||
<MudContainer MaxWidth="MaxWidth.Large" Class="mt-8">
|
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-8">
|
||||||
@if (_loading)
|
@if (_loading)
|
||||||
{
|
{
|
||||||
<MudProgressCircular Indeterminate />
|
<MudProgressCircular Indeterminate />
|
||||||
@@ -21,37 +21,42 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudCard>
|
<MudSplitPanel>
|
||||||
<!-- Заголовок с обложкой -->
|
<FirstPanel>
|
||||||
<MudCardHeader>
|
<MudCard>
|
||||||
<CardHeaderContent>
|
<!-- Заголовок с обложкой -->
|
||||||
<PlaylistHeader Playlist="@_playlist" />
|
<MudCardHeader>
|
||||||
</CardHeaderContent>
|
<CardHeaderContent>
|
||||||
</MudCardHeader>
|
<PlaylistHeader Playlist="@_playlist" />
|
||||||
|
</CardHeaderContent>
|
||||||
|
</MudCardHeader>
|
||||||
|
|
||||||
<MudCardContent>
|
<MudCardContent>
|
||||||
|
<MudIconButton Icon="@Icons.Material.Filled.Refresh" OnClick="LoadTracks" Disabled="_tracksLoading" Size="Size.Medium" />
|
||||||
|
<TracksTable @ref="_tracksTableRef"
|
||||||
|
ShareToken="@Token"
|
||||||
|
CanPlay="@_canPlay"
|
||||||
|
CanRemove="@_canRemove"
|
||||||
|
/>
|
||||||
|
</MudCardContent>
|
||||||
|
</MudCard>
|
||||||
|
</FirstPanel>
|
||||||
|
<SecondPanel>
|
||||||
@if (_canAdd)
|
@if (_canAdd)
|
||||||
{
|
{
|
||||||
<AddTrackSection ShareToken="@Token"
|
<MudCard>
|
||||||
OnTrackAdded="LoadTracks"
|
<MudCardHeader>
|
||||||
OnTrackRemoved="LoadTracks"
|
<CardHeaderContent>
|
||||||
/>
|
<MudText Typo="Typo.h5" Color="Color.Primary">Добавление треков</MudText>
|
||||||
|
</CardHeaderContent>
|
||||||
|
</MudCardHeader>
|
||||||
|
<MudCardContent>
|
||||||
|
<AddTrackSection ShareToken="@Token" OnTrackAdded="LoadTracks" OnTrackRemoved="LoadTracks" />
|
||||||
|
</MudCardContent>
|
||||||
|
</MudCard>
|
||||||
}
|
}
|
||||||
|
</SecondPanel>
|
||||||
<!-- Список треков -->
|
</MudSplitPanel>
|
||||||
<MudStack Row Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center" Class="mb-4">
|
|
||||||
<MudText Typo="Typo.h6">Треки</MudText>
|
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.Refresh" OnClick="LoadTracks" Disabled="_tracksLoading" Size="Size.Medium" />
|
|
||||||
</MudStack>
|
|
||||||
|
|
||||||
<TracksTable @ref="_tracksTableRef"
|
|
||||||
ShareToken="@Token"
|
|
||||||
CanPlay="@_canPlay"
|
|
||||||
CanRemove="@_canRemove"
|
|
||||||
CurrentPlayingTrackId="_currentTrackId"
|
|
||||||
/>
|
|
||||||
</MudCardContent>
|
|
||||||
</MudCard>
|
|
||||||
}
|
}
|
||||||
</MudContainer>
|
</MudContainer>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user