Added playlists view context menu for rename, lock/unlock, and delete.
This commit is contained in:
@@ -681,18 +681,6 @@ public partial class PlaylistDetailViewModel : ViewModelBase
|
||||
return;
|
||||
|
||||
_playlistManager.RemovePlaylist(Playlist);
|
||||
|
||||
if (_playlistManager.CurrentPlaylist == Playlist)
|
||||
{
|
||||
if (_playlistManager.Playlists.Count > 0)
|
||||
{
|
||||
_playlistManager.CurrentPlaylist = _playlistManager.Playlists.ElementAt(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_playlistManager.CurrentPlaylist = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SortAllSongs(SortItem? sortItem)
|
||||
|
||||
@@ -35,6 +35,19 @@ public partial class PlaylistItemViewModel : ObservableObject
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isLocked;
|
||||
public bool IsLocked
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isLocked;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetProperty(ref _isLocked, value);
|
||||
}
|
||||
}
|
||||
|
||||
public PlaylistItemViewModel(Playlist playlist)
|
||||
{
|
||||
Playlist = playlist;
|
||||
@@ -55,6 +68,7 @@ public partial class PlaylistItemViewModel : ObservableObject
|
||||
private void UpdateMetaData()
|
||||
{
|
||||
Name = Playlist.Name ?? "Untitled Playlist";
|
||||
IsLocked = Playlist.IsLocked;
|
||||
|
||||
TimeSpan total = TimeSpan.FromSeconds(Playlist.Songs.Sum(s => s.Song.Length.TotalSeconds));
|
||||
Summary = $"{Playlist.Songs.Count} songs / {total:h\\:mm\\:ss}";
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
using Harmonia.Core.Player;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Harmonia.Core.Player;
|
||||
using Harmonia.Core.Playlists;
|
||||
using Harmonia.WinUI.Messaging;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Harmonia.WinUI.ViewModels;
|
||||
|
||||
@@ -11,6 +14,7 @@ public partial class PlaylistsViewModel : ViewModelBase
|
||||
{
|
||||
private readonly IPlaylistManager _playlistManager;
|
||||
private readonly IAudioPlayer _audioPlayer;
|
||||
private readonly IMessageService _messageService;
|
||||
private readonly DispatcherQueue _dispatcherQueue;
|
||||
|
||||
private ObservableCollection<PlaylistItemViewModel> _playlists = [];
|
||||
@@ -55,12 +59,31 @@ public partial class PlaylistsViewModel : ViewModelBase
|
||||
}
|
||||
}
|
||||
|
||||
public PlaylistsViewModel(IPlaylistManager playlistManager, IAudioPlayer audioPlayer)
|
||||
private PlaylistItemViewModel? _flyoutPlaylist = null;
|
||||
public PlaylistItemViewModel? FlyoutPlaylist
|
||||
{
|
||||
get
|
||||
{
|
||||
return _flyoutPlaylist;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetProperty(ref _flyoutPlaylist, value);
|
||||
}
|
||||
}
|
||||
|
||||
public IAsyncRelayCommand<PlaylistItemViewModel?> RenamePlaylistCommand { get; }
|
||||
public IRelayCommand<PlaylistItemViewModel?> LockPlaylistCommand { get; }
|
||||
public IRelayCommand<PlaylistItemViewModel?> UnlockPlaylistCommand { get; }
|
||||
public IAsyncRelayCommand<PlaylistItemViewModel?> DeletePlaylistCommand { get; }
|
||||
|
||||
public PlaylistsViewModel(IPlaylistManager playlistManager, IAudioPlayer audioPlayer, IMessageService messageService)
|
||||
{
|
||||
_playlistManager = playlistManager;
|
||||
_playlistManager.PlaylistAdded += OnPlaylistAdded;
|
||||
_playlistManager.PlaylistRemoved += OnPlaylistRemoved;
|
||||
_playlistManager.CurrentPlaylistChanged += OnCurrentPlaylistChanged;
|
||||
_messageService = messageService;
|
||||
|
||||
_audioPlayer = audioPlayer;
|
||||
_audioPlayer.PlayingSongChanged += OnPlayingSongChanged;
|
||||
@@ -70,6 +93,11 @@ public partial class PlaylistsViewModel : ViewModelBase
|
||||
_playlists = new ObservableCollection<PlaylistItemViewModel>(_playlistManager.Playlists.Select(p => new PlaylistItemViewModel(p)));
|
||||
_selectedPlaylist = _playlists.FirstOrDefault(pv => pv.Playlist == _playlistManager.CurrentPlaylist);
|
||||
_activePlaylist = _playlists.FirstOrDefault(pv => pv.Playlist == _audioPlayer.Playlist);
|
||||
|
||||
RenamePlaylistCommand = new AsyncRelayCommand<PlaylistItemViewModel?>(RenamePlaylist);
|
||||
LockPlaylistCommand = new RelayCommand<PlaylistItemViewModel?>(LockPlaylist);
|
||||
UnlockPlaylistCommand = new RelayCommand<PlaylistItemViewModel?>(UnlockPlaylist);
|
||||
DeletePlaylistCommand = new AsyncRelayCommand<PlaylistItemViewModel?>(DeletePlaylistAsync);
|
||||
}
|
||||
|
||||
private void OnCurrentPlaylistChanged(object? sender, EventArgs e)
|
||||
@@ -102,4 +130,57 @@ public partial class PlaylistsViewModel : ViewModelBase
|
||||
{
|
||||
ActivePlaylist = Playlists.FirstOrDefault(pv => pv.Playlist == _audioPlayer.Playlist);
|
||||
}
|
||||
|
||||
private async Task RenamePlaylist(PlaylistItemViewModel? playlistItem)
|
||||
{
|
||||
if (playlistItem is null || playlistItem.Playlist is null)
|
||||
return;
|
||||
|
||||
Playlist playlist = playlistItem.Playlist;
|
||||
|
||||
string newName = await _messageService.InputTextAsync(
|
||||
$"Rename Playlist - {playlist.Name}",
|
||||
"Enter a new name for the playlist:",
|
||||
playlist.Name ?? string.Empty);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(newName))
|
||||
return;
|
||||
|
||||
playlist.SetName(newName);
|
||||
}
|
||||
|
||||
private void LockPlaylist(PlaylistItemViewModel? playlistItem)
|
||||
{
|
||||
if (playlistItem is null || playlistItem.Playlist is null)
|
||||
return;
|
||||
|
||||
Playlist playlist = playlistItem.Playlist;
|
||||
|
||||
playlist.Lock();
|
||||
}
|
||||
|
||||
private void UnlockPlaylist(PlaylistItemViewModel? playlistItem)
|
||||
{
|
||||
if (playlistItem is null || playlistItem.Playlist is null)
|
||||
return;
|
||||
|
||||
Playlist playlist = playlistItem.Playlist;
|
||||
|
||||
playlist.Unlock();
|
||||
}
|
||||
|
||||
private async Task DeletePlaylistAsync(PlaylistItemViewModel? playlistItem)
|
||||
{
|
||||
if (playlistItem is null || playlistItem.Playlist is null)
|
||||
return;
|
||||
|
||||
Playlist playlist = playlistItem.Playlist;
|
||||
|
||||
bool confirmed = await _messageService.ConfirmAsync($"Delete Playlist - {playlist.Name}", "Are you sure you want to delete this playlist?");
|
||||
|
||||
if (!confirmed)
|
||||
return;
|
||||
|
||||
_playlistManager.RemovePlaylist(playlist);
|
||||
}
|
||||
}
|
||||
@@ -7,11 +7,15 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="using:Harmonia.WinUI.ViewModels"
|
||||
xmlns:converter="using:Harmonia.WinUI.Converters"
|
||||
xmlns:playlists="using:Harmonia.Core.Playlists"
|
||||
DataContext="{Binding Source={StaticResource Locator}, Path=PlaylistsViewModel}"
|
||||
d:DataContext="{d:DesignInstance Type=vm:PlaylistsViewModel, IsDesignTimeCreatable=True}"
|
||||
mc:Ignorable="d">
|
||||
<UserControl.Resources>
|
||||
<converter:BooleanToVisibilityConverter x:Key="BoolToVis" />
|
||||
<converter:BooleanToVisibilityConverter x:Key="InverseBoolToVis" TrueValue="Collapsed" FalseValue="Visible"/>
|
||||
|
||||
<SolidColorBrush x:Key="PlaylistItemIconBrush" Color="#dddddd"/>
|
||||
<SolidColorBrush x:Key="PlaylistItemTitleBrush" Color="#dddddd"/>
|
||||
<SolidColorBrush x:Key="PlaylistItemSubtitleBrush" Color="#aaaaaa"/>
|
||||
@@ -76,7 +80,44 @@
|
||||
Name="PlaylistsListView"
|
||||
ItemsSource="{Binding Playlists, Mode=OneWay}"
|
||||
SelectedItem="{Binding SelectedPlaylist, Mode=TwoWay}"
|
||||
ItemTemplate="{StaticResource PlaylistTemplate}">
|
||||
ItemTemplate="{StaticResource PlaylistTemplate}"
|
||||
RightTapped="PlaylistsListView_RightTapped">
|
||||
<ListView.ContextFlyout>
|
||||
<MenuFlyout
|
||||
x:Name="PlaylistListViewMenuFlyout"
|
||||
ShouldConstrainToRootBounds="False"
|
||||
SystemBackdrop="{StaticResource AcrylicBackgroundFillColorDefaultBackdrop}">
|
||||
<MenuFlyout.MenuFlyoutPresenterStyle>
|
||||
<Style TargetType="MenuFlyoutPresenter">
|
||||
<Setter Property="Padding" Value="10"></Setter>
|
||||
<Setter Property="Background" Value="Transparent"></Setter>
|
||||
</Style>
|
||||
</MenuFlyout.MenuFlyoutPresenterStyle>
|
||||
|
||||
<MenuFlyoutItem Text="{Binding FlyoutPlaylist.Name}" IsEnabled="False" FontWeight="SemiLight">
|
||||
<MenuFlyoutItem.Resources>
|
||||
<SolidColorBrush x:Key="MenuFlyoutItemForegroundDisabled" Color="#aaaaaa"/>
|
||||
</MenuFlyoutItem.Resources>
|
||||
</MenuFlyoutItem>
|
||||
|
||||
<MenuFlyoutSeparator></MenuFlyoutSeparator>
|
||||
|
||||
<MenuFlyoutItem Text="Rename" Command="{Binding RenamePlaylistCommand}" CommandParameter="{Binding FlyoutPlaylist}">
|
||||
</MenuFlyoutItem>
|
||||
|
||||
<MenuFlyoutItem Text="Lock" Command="{Binding LockPlaylistCommand}" CommandParameter="{Binding FlyoutPlaylist}" Visibility="{Binding FlyoutPlaylist.IsLocked, Converter={StaticResource InverseBoolToVis}}">
|
||||
</MenuFlyoutItem>
|
||||
|
||||
<MenuFlyoutItem Text="Unlock" Command="{Binding UnlockPlaylistCommand}" CommandParameter="{Binding FlyoutPlaylist}" Visibility="{Binding FlyoutPlaylist.IsLocked, Converter={StaticResource BoolToVis}}">
|
||||
</MenuFlyoutItem>
|
||||
|
||||
<MenuFlyoutSeparator></MenuFlyoutSeparator>
|
||||
|
||||
<MenuFlyoutItem Text="Remove" Foreground="#ff99a4" Command="{Binding DeletePlaylistCommand}" CommandParameter="{Binding FlyoutPlaylist}">
|
||||
</MenuFlyoutItem>
|
||||
|
||||
</MenuFlyout>
|
||||
</ListView.ContextFlyout>
|
||||
</ListView>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -19,6 +19,16 @@ public sealed partial class PlaylistsView : UserControl
|
||||
_viewModel.PropertyChanged += OnViewModelPropertyChanged;
|
||||
|
||||
PlaylistsListView.ContainerContentChanging += OnContainerContentChanging;
|
||||
|
||||
foreach (MenuFlyoutItemBase item in PlaylistListViewMenuFlyout.Items)
|
||||
{
|
||||
item.DataContext = _viewModel;
|
||||
}
|
||||
}
|
||||
|
||||
private void PlaylistsListView_RightTapped(object sender, Microsoft.UI.Xaml.Input.RightTappedRoutedEventArgs e)
|
||||
{
|
||||
_viewModel.FlyoutPlaylist = (e.OriginalSource as FrameworkElement)?.DataContext as PlaylistItemViewModel;
|
||||
}
|
||||
|
||||
private void OnContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
|
||||
|
||||
Reference in New Issue
Block a user