Compare commits

..

4 Commits

6 changed files with 115 additions and 64 deletions

View File

@@ -6,27 +6,6 @@ public class PlaylistRepository : JsonFileRepository<Playlist>, IPlaylistReposit
{
protected override string DirectoryName => Path.Combine("Playlists");
//public PlaylistRepository()
//{
// List<Playlist> playlists = Get();
// foreach (Playlist playlist in playlists)
// {
// playlist.PlaylistUpdated += OnPlaylistUpdated;
// }
// if (playlists.Count == 0)
// AddPlaylist();
//}
//private void OnPlaylistUpdated(object? sender, PlaylistUpdatedEventArgs e)
//{
// if (sender is not Playlist playlist)
// return;
// Save(playlist);
//}
public Playlist? GetPlaylist(PlaylistSong playlistSong)
{
return Get().FirstOrDefault(playlist => playlist.Songs.Contains(playlistSong));
@@ -45,28 +24,4 @@ public class PlaylistRepository : JsonFileRepository<Playlist>, IPlaylistReposit
throw new Exception("Unable to determine new fileName");
}
//public event EventHandler<PlaylistAddedEventArgs>? PlaylistAdded;
//public event EventHandler<PlaylistRemovedEventArgs>? PlaylistRemoved;
//public void AddPlaylist()
//{
// Playlist playlist = new()
// {
// Name = "New Playlist"
// };
// playlist.PlaylistUpdated += OnPlaylistUpdated;
// Save(playlist);
// PlaylistAdded?.Invoke(this, new(playlist));
//}
//public void RemovePlaylist(Playlist playlist)
//{
// playlist.PlaylistUpdated -= OnPlaylistUpdated;
// Delete(playlist);
// PlaylistRemoved?.Invoke(this, new(playlist));
//}
}

View File

@@ -43,7 +43,12 @@ public partial class PlaylistDetailViewModel : ViewModelBase
private DispatcherQueueTimer? _filterTimer;
public Playlist? Playlist { get; private set; }
private Playlist? _playlist;
public Playlist? Playlist
{
get => _playlist;
private set => SetProperty(ref _playlist, value);
}
private PlaylistSong? _playingSong;
public PlaylistSong? PlayingSong

View File

@@ -0,0 +1,47 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Harmonia.Core.Playlists;
using System;
using System.Linq;
namespace Harmonia.WinUI.ViewModels;
public partial class PlaylistItemViewModel : ObservableObject
{
public Playlist Playlist { get; private set; }
private string _summary = string.Empty;
public string Summary
{
get
{
return _summary;
}
set
{
SetProperty(ref _summary, value);
}
}
public PlaylistItemViewModel(Playlist playlist)
{
Playlist = playlist;
Playlist.PlaylistUpdated += OnPlaylistUpdated;
UpdateMetaData();
}
public void Unsubscribe()
{
Playlist.PlaylistUpdated -= OnPlaylistUpdated;
}
private void OnPlaylistUpdated(object? sender, EventArgs e)
{
UpdateMetaData();
}
private void UpdateMetaData()
{
TimeSpan total = TimeSpan.FromSeconds(Playlist.Songs.Sum(s => s.Song.Length.TotalSeconds));
Summary = $"{Playlist.Songs.Count} songs / {total:h\\:mm\\:ss}";
}
}

View File

@@ -1,6 +1,8 @@
using Harmonia.Core.Playlists;
using CommunityToolkit.Mvvm.ComponentModel;
using Harmonia.Core.Playlists;
using System;
using System.Collections.ObjectModel;
using System.Linq;
namespace Harmonia.WinUI.ViewModels;
@@ -8,8 +10,8 @@ public partial class PlaylistsViewModel : ViewModelBase
{
private readonly IPlaylistManager _playlistManager;
private ObservableCollection<Playlist> _playlists = [];
public ObservableCollection<Playlist> Playlists
private ObservableCollection<PlaylistItemViewModel> _playlists = [];
public ObservableCollection<PlaylistItemViewModel> Playlists
{
get
{
@@ -21,8 +23,8 @@ public partial class PlaylistsViewModel : ViewModelBase
}
}
private Playlist? _selectedPlaylist = null;
public Playlist? SelectedPlaylist
private PlaylistItemViewModel? _selectedPlaylist = null;
public PlaylistItemViewModel? SelectedPlaylist
{
get
{
@@ -32,7 +34,7 @@ public partial class PlaylistsViewModel : ViewModelBase
{
if (SetProperty(ref _selectedPlaylist, value))
{
_playlistManager.CurrentPlaylist = value;
_playlistManager.CurrentPlaylist = value?.Playlist;
}
}
}
@@ -44,22 +46,28 @@ public partial class PlaylistsViewModel : ViewModelBase
_playlistManager.PlaylistRemoved += OnPlaylistRemoved;
_playlistManager.CurrentPlaylistChanged += OnCurrentPlaylistChanged;
_playlists = new(_playlistManager.Playlists);
_selectedPlaylist = _playlistManager.CurrentPlaylist;
_playlists = new ObservableCollection<PlaylistItemViewModel>(_playlistManager.Playlists.Select(p => new PlaylistItemViewModel(p)));
_selectedPlaylist = _playlists.FirstOrDefault(pv => pv.Playlist == _playlistManager.CurrentPlaylist);
}
private void OnCurrentPlaylistChanged(object? sender, EventArgs e)
{
SelectedPlaylist = _playlistManager.CurrentPlaylist;
SelectedPlaylist = _playlists.FirstOrDefault(pv => pv.Playlist == _playlistManager.CurrentPlaylist);
}
private void OnPlaylistAdded(object? sender, PlaylistAddedEventArgs e)
{
Playlists.Add(e.Playlist);
Playlists.Add(new PlaylistItemViewModel(e.Playlist));
}
private void OnPlaylistRemoved(object? sender, PlaylistRemovedEventArgs e)
{
Playlists.Remove(e.Playlist);
var playlistView = Playlists.FirstOrDefault(pv => pv.Playlist == e.Playlist);
if (playlistView != null)
{
playlistView.Unsubscribe();
Playlists.Remove(playlistView);
}
}
}

View File

@@ -58,6 +58,22 @@ public sealed partial class PlaylistDetailView : UserControl
UpdateListViewItemStyle(listViewItem, true);
}
else if (e.PropertyName == nameof(_viewModel.Playlist))
{
ScrollToTop();
}
}
private void ScrollToTop()
{
if (PlaylistListView.FindDescendant<ScrollViewer>() is ScrollViewer scrollViewer)
{
scrollViewer.ChangeView(null, 0, null, disableAnimation: false);
}
else if (_viewModel.FilteredPlaylistSongs.FirstOrDefault() is PlaylistSong firstSong)
{
PlaylistListView.ScrollIntoView(firstSong);
}
}
private void UpdateListViewItemStyle(FrameworkElement listViewItem, bool isPlaying)

View File

@@ -12,13 +12,33 @@
d:DataContext="{d:DesignInstance Type=vm:PlaylistsViewModel, IsDesignTimeCreatable=True}"
mc:Ignorable="d">
<UserControl.Resources>
<DataTemplate x:Key="PlaylistTemplate" x:DataType="playlists:Playlist">
<StackPanel Orientation="Horizontal" Spacing="8" VerticalAlignment="Bottom">
<SolidColorBrush x:Key="PlaylistItemSubtitleBrush" Color="#aaaaaa"/>
<!-- Playlist Item Subtitle Text Block -->
<Style x:Key="PlaylistSubtitleTextBlock" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource PlaylistItemSubtitleBrush}"/>
<Setter Property="FontSize" Value="13"/>
<Setter Property="LineStackingStrategy" Value="BlockLineHeight"/>
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
<Setter Property="LineHeight" Value="0"/>
</Style>
<DataTemplate x:Key="PlaylistTemplate" x:DataType="vm:PlaylistItemViewModel">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="8" VerticalAlignment="Center">
<Viewbox Height="24" Width="24">
<PathIcon Data="{StaticResource MusicNoteList}" />
</Viewbox>
<TextBlock Text="{x:Bind Name}" FontSize="16" VerticalAlignment="Center" />
<TextBlock Text="{x:Bind Playlist.Name}" FontSize="16" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center" Spacing="8">
<TextBlock Text="{x:Bind Summary, Mode=OneWay}" Style="{StaticResource PlaylistSubtitleTextBlock}" />
</StackPanel>
</Grid>
</DataTemplate>
</UserControl.Resources>
<Grid Margin="10">