Files
WindowsMusicPlayer-TheUntam…/The Untamed Music Player/ViewModels/LocalAlbumsViewModel.cs
2025-08-16 22:34:46 +08:00

419 lines
12 KiB
C#

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Media.Animation;
using The_Untamed_Music_Player.Contracts.Services;
using The_Untamed_Music_Player.Helpers;
using The_Untamed_Music_Player.Models;
using The_Untamed_Music_Player.Views;
namespace The_Untamed_Music_Player.ViewModels;
public partial class LocalAlbumsViewModel : ObservableRecipient
{
private readonly ILocalSettingsService _localSettingsService =
App.GetService<ILocalSettingsService>();
private bool _groupMode = true;
private List<LocalAlbumInfo> _albumList = [.. Data.MusicLibrary.Albums.Values];
public List<string> SortBy { get; set; } = [.. "Albums_SortBy".GetLocalized().Split(", ")];
public List<GroupInfoList> GroupedAlbumList { get; set; } = [];
public List<LocalAlbumInfo> NotGroupedAlbumList { get; set; } = [];
public List<string> Genres { get; set; } = Data.MusicLibrary.Genres;
[ObservableProperty]
public partial bool IsProgressRingActive { get; set; } = true;
[ObservableProperty]
public partial byte SortMode { get; set; } = 0;
partial void OnSortModeChanged(byte value)
{
SortByStr = SortBy[value];
SetGroupMode();
SaveSortModeAsync();
}
[ObservableProperty]
public partial string SortByStr { get; set; } = "";
[ObservableProperty]
public partial int GenreMode { get; set; } = 0;
partial void OnGenreModeChanged(int value)
{
if (Genres.Count > 0 && value < Genres.Count)
{
GenreStr = Genres[value];
}
SaveGenreModeAsync();
}
[ObservableProperty]
public partial string GenreStr { get; set; } = "";
public LocalAlbumsViewModel()
: base(StrongReferenceMessenger.Default)
{
LoadModeAndAlbumList();
Data.LocalAlbumsViewModel = this;
}
public async void LoadModeAndAlbumList()
{
_albumList = [.. Data.MusicLibrary.Albums.Values];
if (_albumList.Count == 0)
{
return;
}
Genres = Data.MusicLibrary.Genres;
await LoadSortModeAsync();
await LoadGenreModeAsync();
await FilterAlbums();
OnPropertyChanged(nameof(GroupedAlbumList));
OnPropertyChanged(nameof(NotGroupedAlbumList));
OnPropertyChanged(nameof(Genres));
IsProgressRingActive = false;
}
public async Task SortAlbums()
{
var sortTask = SortMode switch
{
0 => SortAlbumsByTitleAscending(),
1 => SortAlbumsByTitleDescending(),
2 => SortAlbumsByYearAscending(),
3 => SortAlbumsByYearDescending(),
4 => SortAlbumsByArtistAscending(),
5 => SortAlbumsByArtistDescending(),
6 => SortAlbumsByModifiedTimeAscending(),
7 => SortAlbumsByModifiedTimeDescending(),
_ => SortAlbumsByTitleAscending(),
};
await sortTask;
}
private void SetGroupMode()
{
_groupMode = SortMode switch
{
0 or 1 or 2 or 3 or 4 or 5 => true,
_ => false,
};
}
public async Task FilterAlbums()
{
GroupedAlbumList =
[
.. _albumList
.GroupBy(m => TitleComparer.GetGroupKey(m.Name[0]))
.Select(g => new GroupInfoList(g) { Key = g.Key }),
];
NotGroupedAlbumList = [.. _albumList];
if (GenreMode == 0)
{
await SortAlbums();
return;
}
var genreToFilter = Genres[GenreMode];
var filterGroupedTask = Task.Run(() =>
{
// 过滤GroupedSongList
foreach (var group in GroupedAlbumList)
{
var filteredItems = group
.Where(item =>
item is LocalAlbumInfo localAlbumInfo
&& localAlbumInfo.GenreStr == genreToFilter
)
.ToList();
group.Clear();
foreach (var item in filteredItems)
{
group.Add(item);
}
}
});
var filterNotGroupedTask = Task.Run(() =>
{
// 过滤NotGroupedSongList
var filteredSongs = NotGroupedAlbumList
.Where(localAlbumInfo => localAlbumInfo.GenreStr == genreToFilter)
.ToList();
NotGroupedAlbumList.Clear();
foreach (var song in filteredSongs)
{
NotGroupedAlbumList.Add(song);
}
});
await Task.WhenAll(filterGroupedTask, filterNotGroupedTask);
await SortAlbums();
}
public ICollectionView GetAlbumGridViewSource(
ICollectionView grouped,
List<LocalAlbumInfo> notgrouped
)
{
return _groupMode ? grouped : new CollectionViewSource { Source = notgrouped }.View;
}
public async Task SortAlbumsByTitleAscending()
{
await Task.Run(() =>
{
var sortedGroups = GroupedAlbumList
.SelectMany(group => group)
.OfType<LocalAlbumInfo>()
.OrderBy(m => m.Name, new AlbumTitleComparer())
.GroupBy(m =>
m.Name == "SongInfo_UnknownAlbum".GetLocalized()
? "..."
: TitleComparer.GetGroupKey(m.Name[0])
)
.Select(g => new GroupInfoList(g) { Key = g.Key });
GroupedAlbumList = [.. sortedGroups];
});
}
public async Task SortAlbumsByTitleDescending()
{
await Task.Run(() =>
{
var sortedGroups = GroupedAlbumList
.SelectMany(group => group)
.OfType<LocalAlbumInfo>()
.OrderByDescending(m => m.Name, new AlbumTitleComparer())
.GroupBy(m =>
m.Name == "SongInfo_UnknownAlbum".GetLocalized()
? "..."
: TitleComparer.GetGroupKey(m.Name[0])
)
.Select(g => new GroupInfoList(g) { Key = g.Key });
GroupedAlbumList = [.. sortedGroups];
});
}
public async Task SortAlbumsByYearAscending()
{
await Task.Run(() =>
{
var sortedGroups = GroupedAlbumList
.SelectMany(group => group)
.OfType<LocalAlbumInfo>()
.OrderBy(m => m.Year)
.GroupBy(m => m.Year == 0 ? "..." : $"{m.Year}")
.Select(g => new GroupInfoList(g) { Key = g.Key });
GroupedAlbumList = [.. sortedGroups];
});
}
public async Task SortAlbumsByYearDescending()
{
await Task.Run(() =>
{
var sortedGroups = GroupedAlbumList
.SelectMany(group => group)
.OfType<LocalAlbumInfo>()
.OrderByDescending(m => m.Year)
.GroupBy(m => m.Year == 0 ? "..." : $"{m.Year}")
.Select(g => new GroupInfoList(g) { Key = g.Key });
GroupedAlbumList = [.. sortedGroups];
});
}
public async Task SortAlbumsByArtistAscending()
{
await Task.Run(() =>
{
var sortedGroups = GroupedAlbumList
.SelectMany(group => group)
.OfType<LocalAlbumInfo>()
.OrderBy(m => m, new AlbumArtistComparer())
.GroupBy(m => m.ArtistsStr)
.Select(g => new GroupInfoList(g) { Key = g.Key });
GroupedAlbumList = [.. sortedGroups];
});
}
public async Task SortAlbumsByArtistDescending()
{
await Task.Run(() =>
{
var sortedGroups = GroupedAlbumList
.SelectMany(group => group)
.OfType<LocalAlbumInfo>()
.OrderByDescending(m => m, new AlbumArtistComparer())
.GroupBy(m => m.ArtistsStr)
.Select(g => new GroupInfoList(g) { Key = g.Key });
GroupedAlbumList = [.. sortedGroups];
});
}
public async Task SortAlbumsByModifiedTimeAscending()
{
await Task.Run(() =>
{
var sortedGroups = NotGroupedAlbumList.OrderBy(m => m.ModifiedDate);
NotGroupedAlbumList = [.. sortedGroups];
});
}
public async Task SortAlbumsByModifiedTimeDescending()
{
await Task.Run(() =>
{
var sortedGroups = NotGroupedAlbumList.OrderByDescending(m => m.ModifiedDate);
NotGroupedAlbumList = [.. sortedGroups];
});
}
public async void SortByListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var currentsortmode = SortMode;
if (sender is ListView listView && listView.SelectedIndex is int selectedIndex)
{
SortMode = (byte)selectedIndex;
if (SortMode != currentsortmode)
{
IsProgressRingActive = true;
await SortAlbums();
OnPropertyChanged(nameof(GroupedAlbumList));
OnPropertyChanged(nameof(NotGroupedAlbumList));
IsProgressRingActive = false;
}
}
}
public void SortByListView_Loaded(object sender, RoutedEventArgs e)
{
(sender as ListView)!.SelectedIndex = SortMode;
}
public async void GenreListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var currentGenreMode = GenreMode;
if (sender is ListView listView && listView.SelectedIndex is int selectedIndex)
{
GenreMode = selectedIndex;
if (GenreMode != currentGenreMode)
{
IsProgressRingActive = true;
await FilterAlbums();
OnPropertyChanged(nameof(GroupedAlbumList));
OnPropertyChanged(nameof(NotGroupedAlbumList));
IsProgressRingActive = false;
}
}
}
public void GenreListView_Loaded(object sender, RoutedEventArgs e)
{
(sender as ListView)!.SelectedIndex = GenreMode;
}
public void PlayButton_Click(LocalAlbumInfo info)
{
var tempList = Data.MusicLibrary.GetSongsByAlbum(info);
var songList = tempList.ToList();
Data.MusicPlayer.SetPlayQueue($"LocalSongs:Album:{info.Name}", songList, 0, SortMode);
Data.MusicPlayer.PlaySongByInfo(songList[0]);
}
public void PlayNextButton_Click(LocalAlbumInfo info)
{
var tempList = Data.MusicLibrary.GetSongsByAlbum(info);
var songList = tempList.ToList();
if (Data.MusicPlayer.PlayQueue.Count == 0)
{
Data.MusicPlayer.SetPlayQueue($"LocalSongs:Album:{info.Name}", songList, 0, SortMode);
Data.MusicPlayer.PlaySongByInfo(songList[0]);
}
else
{
Data.MusicPlayer.AddSongsToNextPlay(songList);
}
}
public void ShowArtistButton_Click(LocalAlbumInfo info)
{
var localArtistInfo = Data.MusicLibrary.GetArtistInfoBySong(info.Artists[0]);
if (localArtistInfo is not null)
{
Data.SelectedLocalArtist = localArtistInfo;
Data.ShellPage!.Navigate(
nameof(LocalArtistDetailPage),
"",
new SuppressNavigationTransitionInfo()
);
}
}
public async Task LoadSortModeAsync()
{
SortMode = await _localSettingsService.ReadSettingAsync<byte>("AlbumSortMode");
SortByStr = SortBy[SortMode];
}
public async Task LoadGenreModeAsync()
{
GenreMode = await _localSettingsService.ReadSettingAsync<int>("AlbumGenreMode");
if (Genres.Count > 0 && GenreMode < Genres.Count)
{
GenreStr = Genres[GenreMode];
}
}
public async void SaveSortModeAsync()
{
await _localSettingsService.SaveSettingAsync("AlbumSortMode", SortMode);
}
public async void SaveGenreModeAsync()
{
await _localSettingsService.SaveSettingAsync("AlbumGenreMode", GenreMode);
}
public double GetAlbumGridViewOpacity(bool isActive)
{
return isActive ? 0 : 1;
}
public double GetZoomedOutViewGridWidth(byte sortmode)
{
return sortmode switch
{
0 or 1 => 71,
_ => 426,
};
}
public Thickness GetZoomedOutViewTextBlockMargin(byte sortmode)
{
return sortmode switch
{
0 or 1 => new Thickness(0, 0, 0, 0),
_ => new Thickness(15, 0, 15, 0),
};
}
}