Added playlist renaming functionality.

This commit is contained in:
2026-08-03 23:49:21 -04:00
parent de16ac6240
commit cd6f9c382e
8 changed files with 97 additions and 1 deletions

View File

@@ -14,6 +14,24 @@ public class Playlist
public event EventHandler<PlaylistUpdatedEventArgs>? PlaylistUpdated; public event EventHandler<PlaylistUpdatedEventArgs>? PlaylistUpdated;
public void SetName(string name)
{
if (string.Equals(Name, name, StringComparison.Ordinal))
return;
Name = name;
PlaylistUpdatedEventArgs eventArgs = new()
{
Action = PlaylistUpdateAction.Rename,
Index = -1,
Count = 0,
Songs = []
};
PlaylistUpdated?.Invoke(this, eventArgs);
}
public void Lock() public void Lock()
{ {
if (IsLocked) if (IsLocked)

View File

@@ -22,6 +22,7 @@ public enum PlaylistUpdateAction
/// The tags of the songs in the collection were refreshed. /// The tags of the songs in the collection were refreshed.
/// </summary> /// </summary>
Refresh, Refresh,
Rename,
Lock, Lock,
Unlock Unlock
} }

View File

@@ -5,4 +5,5 @@ namespace Harmonia.WinUI.Messaging;
public interface IMessageService public interface IMessageService
{ {
Task<bool> ConfirmAsync(string title, string message); Task<bool> ConfirmAsync(string title, string message);
Task<string> InputTextAsync(string title, string message, string defaultText = "");
} }

View File

@@ -27,4 +27,44 @@ public class WindowsMessageService : IMessageService
return result == ContentDialogResult.Primary; return result == ContentDialogResult.Primary;
} }
public async Task<string> InputTextAsync(string title, string message, string defaultText = "")
{
TextBox inputTextBox = new()
{
Text = defaultText,
Margin = new Thickness(0, 10, 0, 0)
};
inputTextBox.SelectAll();
ContentDialog dialog = new()
{
XamlRoot = MainWindow.Content.XamlRoot,
Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style,
Title = title,
Content = new StackPanel
{
Children =
{
new TextBlock { Text = message },
inputTextBox
}
},
PrimaryButtonText = "OK",
CloseButtonText = "Cancel",
DefaultButton = ContentDialogButton.Primary
};
ContentDialogResult result = await dialog.ShowAsync();
if (result == ContentDialogResult.Primary)
{
return inputTextBox.Text;
}
else
{
return string.Empty;
}
}
} }

View File

@@ -158,6 +158,7 @@ public partial class PlaylistDetailViewModel : ViewModelBase
public IRelayCommand RandomizeSelectedCommand { get; } public IRelayCommand RandomizeSelectedCommand { get; }
public IRelayCommand ReverseAllCommand { get; } public IRelayCommand ReverseAllCommand { get; }
public IRelayCommand ReverseSelectedCommand { get; } public IRelayCommand ReverseSelectedCommand { get; }
public IAsyncRelayCommand RenamePlaylistCommand { get; }
public IRelayCommand LockPlaylistCommand { get; } public IRelayCommand LockPlaylistCommand { get; }
public IRelayCommand UnlockPlaylistCommand { get; } public IRelayCommand UnlockPlaylistCommand { get; }
@@ -212,6 +213,7 @@ public partial class PlaylistDetailViewModel : ViewModelBase
RandomizeSelectedCommand = new RelayCommand(RandomizeSelectedSongs, AreMultipleSongsSelected); RandomizeSelectedCommand = new RelayCommand(RandomizeSelectedSongs, AreMultipleSongsSelected);
ReverseAllCommand = new RelayCommand(ReverseAllSongs); ReverseAllCommand = new RelayCommand(ReverseAllSongs);
ReverseSelectedCommand = new RelayCommand(ReverseSelectedSongs, AreMultipleSongsSelected); ReverseSelectedCommand = new RelayCommand(ReverseSelectedSongs, AreMultipleSongsSelected);
RenamePlaylistCommand = new AsyncRelayCommand(RenamePlaylist);
LockPlaylistCommand = new RelayCommand(LockPlaylist); LockPlaylistCommand = new RelayCommand(LockPlaylist);
UnlockPlaylistCommand = new RelayCommand(UnlockPlaylist); UnlockPlaylistCommand = new RelayCommand(UnlockPlaylist);
@@ -762,6 +764,22 @@ public partial class PlaylistDetailViewModel : ViewModelBase
Playlist?.Unlock(); Playlist?.Unlock();
} }
private async Task RenamePlaylist()
{
if (Playlist == null)
return;
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);
}
#endregion #endregion
} }

View File

@@ -9,6 +9,19 @@ public partial class PlaylistItemViewModel : ObservableObject
{ {
public Playlist Playlist { get; private set; } public Playlist Playlist { get; private set; }
private string _name = string.Empty;
public string Name
{
get
{
return _name;
}
set
{
SetProperty(ref _name, value);
}
}
private string _summary = string.Empty; private string _summary = string.Empty;
public string Summary public string Summary
{ {
@@ -41,6 +54,8 @@ public partial class PlaylistItemViewModel : ObservableObject
private void UpdateMetaData() private void UpdateMetaData()
{ {
Name = Playlist.Name ?? "Untitled Playlist";
TimeSpan total = TimeSpan.FromSeconds(Playlist.Songs.Sum(s => s.Song.Length.TotalSeconds)); TimeSpan total = TimeSpan.FromSeconds(Playlist.Songs.Sum(s => s.Song.Length.TotalSeconds));
Summary = $"{Playlist.Songs.Count} songs / {total:h\\:mm\\:ss}"; Summary = $"{Playlist.Songs.Count} songs / {total:h\\:mm\\:ss}";
} }

View File

@@ -172,6 +172,9 @@
<MenuFlyoutItem Text="Remove Missing" Command="{Binding RemoveMissingSongsCommand}"> <MenuFlyoutItem Text="Remove Missing" Command="{Binding RemoveMissingSongsCommand}">
</MenuFlyoutItem> </MenuFlyoutItem>
<MenuFlyoutItem Text="Rename Playlist" Command="{Binding RenamePlaylistCommand}">
</MenuFlyoutItem>
<MenuFlyoutItem Text="Lock Playlist" Command="{Binding LockPlaylistCommand}" Visibility="{Binding IsPlaylistLocked, Converter={StaticResource InverseBoolToVis}}"> <MenuFlyoutItem Text="Lock Playlist" Command="{Binding LockPlaylistCommand}" Visibility="{Binding IsPlaylistLocked, Converter={StaticResource InverseBoolToVis}}">
</MenuFlyoutItem> </MenuFlyoutItem>

View File

@@ -33,7 +33,7 @@
<Viewbox Height="24" Width="24"> <Viewbox Height="24" Width="24">
<PathIcon Data="{StaticResource MusicNoteList}" /> <PathIcon Data="{StaticResource MusicNoteList}" />
</Viewbox> </Viewbox>
<TextBlock Text="{x:Bind Playlist.Name}" FontSize="16" VerticalAlignment="Center" /> <TextBlock Text="{x:Bind Name, Mode=OneWay}" FontSize="16" VerticalAlignment="Center" />
</StackPanel> </StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center" Spacing="8"> <StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center" Spacing="8">
<TextBlock Text="{x:Bind Summary, Mode=OneWay}" Style="{StaticResource PlaylistSubtitleTextBlock}" /> <TextBlock Text="{x:Bind Summary, Mode=OneWay}" Style="{StaticResource PlaylistSubtitleTextBlock}" />