This commit is contained in:
Royce551 2021-05-03 20:42:10 -05:00
parent afd51e2b55
commit c9a659248c
11 changed files with 72 additions and 23 deletions

View file

@ -21,8 +21,9 @@ namespace FRESHMusicPlayer
{ {
DataContext = new MainWindowViewModel(), DataContext = new MainWindowViewModel(),
}; };
} }
Name = MainWindowViewModel.ProjectName;
base.OnFrameworkInitializationCompleted(); base.OnFrameworkInitializationCompleted();
} }
} }

View file

@ -43,6 +43,12 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile> <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</None> </None>
<None Update="Backends\libbassflac.dylib">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Backends\libbassflac.so">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Backends\ManagedBass.dll"> <None Update="Backends\ManagedBass.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile> <ExcludeFromSingleFile>true</ExcludeFromSingleFile>

View file

@ -41,5 +41,9 @@ namespace FRESHMusicPlayer.Handlers.Configuration
/// </summary> /// </summary>
public int CurrentTab { get; set; } = 0; public int CurrentTab { get; set; } = 0;
public List<string> AutoImportPaths { get; set; } = new List<string>(); public List<string> AutoImportPaths { get; set; } = new List<string>();
/// <summary>
/// Whether the "downloaded wrong thing" warning was already shown
/// </summary>
public bool WindowsWarningWasShown { get; set; } = false;
} }
} }

View file

@ -68,12 +68,11 @@ namespace FRESHMusicPlayer.ViewModels
{ {
this.RaisePropertyChanged(nameof(CurrentTime)); this.RaisePropertyChanged(nameof(CurrentTime));
this.RaisePropertyChanged(nameof(CurrentTimeSeconds)); this.RaisePropertyChanged(nameof(CurrentTimeSeconds));
this.RaisePropertyChanged(nameof(TotalTime));
this.RaisePropertyChanged(nameof(TotalTimeSeconds));
Player.AvoidNextQueue = false; Player.AvoidNextQueue = false;
} }
private void Player_SongChanged(object sender, EventArgs e) private async void Player_SongChanged(object sender, EventArgs e)
{ {
var track = new Track(Player.FilePath); var track = new Track(Player.FilePath);
Artist = track.Artist; Artist = track.Artist;
@ -84,6 +83,10 @@ namespace FRESHMusicPlayer.ViewModels
this.RaisePropertyChanged(nameof(TotalTimeSeconds)); this.RaisePropertyChanged(nameof(TotalTimeSeconds));
WindowTitle = $"{track.Artist} - {track.Title} | {ProjectName}"; WindowTitle = $"{track.Artist} - {track.Title} | {ProjectName}";
ProgressTimer.Start(); ProgressTimer.Start();
await Task.Delay(100); // small delay to avoid fuckery with bass backend
this.RaisePropertyChanged(nameof(TotalTime));
this.RaisePropertyChanged(nameof(TotalTimeSeconds));
Volume = Player.Volume;
} }
public bool RepeatModeNone { get => Player.Queue.RepeatMode == RepeatMode.None; } public bool RepeatModeNone { get => Player.Queue.RepeatMode == RepeatMode.None; }

View file

@ -19,8 +19,11 @@ namespace FRESHMusicPlayer.ViewModels
public ObservableCollection<QueueManagementEntry> Queue { get; set; } = new(); public ObservableCollection<QueueManagementEntry> Queue { get; set; } = new();
private bool isReady = false;
public void Update() public void Update()
{ {
isReady = false;
Queue.Clear(); Queue.Clear();
int number = 1; int number = 1;
foreach (var track in Player.Queue.Queue) foreach (var track in Player.Queue.Queue)
@ -30,22 +33,24 @@ namespace FRESHMusicPlayer.ViewModels
{ {
Title = info.Title, Title = info.Title,
Artist = info.Artist, Artist = info.Artist,
Position = number Position = number,
Length = info.Length
}; };
entry.IsCurrentTrack = Player.Queue.Position == number; entry.IsCurrentTrack = Player.Queue.Position == number;
Queue.Add(entry); Queue.Add(entry);
number++; number++;
} }
isReady = true;
} }
public void JumpToCommand(int position) public void JumpToCommand(int position)
{ {
Player.Queue.Position = position; Player.Queue.Position = position - 1;
Player.PlayMusic(); Player.PlayMusic();
} }
public void RemoveCommand(int position) public void RemoveCommand(int position)
{ {
Player.Queue.Remove(position); Player.Queue.Remove(position - 1);
} }
private TimeSpan timeRemaining = new(); private TimeSpan timeRemaining = new();
@ -68,15 +73,17 @@ namespace FRESHMusicPlayer.ViewModels
{ {
await Dispatcher.UIThread.InvokeAsync(() => await Dispatcher.UIThread.InvokeAsync(() =>
{ {
TimeSpan x = new(); TimeSpan x = new();
int i = 1; int i = 1;
int i2 = 0;
foreach (var track in Player.Queue.Queue) foreach (var track in Player.Queue.Queue)
{ {
i++; i++;
if (i <= Player.Queue.Position) continue; if (i <= Player.Queue.Position) continue;
var y = Library.GetFallbackTrack(track); var y = Queue[i2];
x += TimeSpan.FromSeconds(y.Length); x += TimeSpan.FromSeconds(y.Length);
i2++;
} }
x -= Player.CurrentTime; x -= Player.CurrentTime;
TimeRemaining = x; TimeRemaining = x;
@ -104,5 +111,6 @@ namespace FRESHMusicPlayer.ViewModels
public string Artist { get; init; } public string Artist { get; init; }
public int Position { get; init; } public int Position { get; init; }
public bool IsCurrentTrack { get; set; } public bool IsCurrentTrack { get; set; }
public int Length { get; init; }
} }
} }

View file

@ -12,7 +12,7 @@ namespace FRESHMusicPlayer.Views
{ {
public class MainWindow : Window public class MainWindow : Window
{ {
private MainWindowViewModel viewModel { get => DataContext as MainWindowViewModel; } private MainWindowViewModel ViewModel { get => DataContext as MainWindowViewModel; }
public MainWindow() public MainWindow()
{ {
InitializeComponent(); InitializeComponent();
@ -43,7 +43,7 @@ namespace FRESHMusicPlayer.Views
private void OnClosing(object sender, CancelEventArgs e) private void OnClosing(object sender, CancelEventArgs e)
{ {
viewModel?.CloseThings(); ViewModel?.CloseThings();
} }
private void OnPlayButtonClick(object sender, RoutedEventArgs e) // TODO: figure out why i need this stuff instead private void OnPlayButtonClick(object sender, RoutedEventArgs e) // TODO: figure out why i need this stuff instead
@ -51,7 +51,7 @@ namespace FRESHMusicPlayer.Views
var cmd = (Button)sender; var cmd = (Button)sender;
if (cmd.DataContext is DatabaseTrack x) if (cmd.DataContext is DatabaseTrack x)
{ {
viewModel?.PlayCommand(x.Path); ViewModel?.PlayCommand(x.Path);
} }
} }
private void OnEnqueueButtonClick(object sender, RoutedEventArgs e) private void OnEnqueueButtonClick(object sender, RoutedEventArgs e)
@ -59,7 +59,7 @@ namespace FRESHMusicPlayer.Views
var cmd = (Button)sender; var cmd = (Button)sender;
if (cmd.DataContext is DatabaseTrack x) if (cmd.DataContext is DatabaseTrack x)
{ {
viewModel?.EnqueueCommand(x.Path); ViewModel?.EnqueueCommand(x.Path);
} }
} }
private void OnDeleteButtonClick(object sender, RoutedEventArgs e) private void OnDeleteButtonClick(object sender, RoutedEventArgs e)
@ -67,7 +67,7 @@ namespace FRESHMusicPlayer.Views
var cmd = (Button)sender; var cmd = (Button)sender;
if (cmd.DataContext is DatabaseTrack x) if (cmd.DataContext is DatabaseTrack x)
{ {
viewModel?.DeleteCommand(x.Path); ViewModel?.DeleteCommand(x.Path);
} }
} }
} }

View file

@ -5,7 +5,7 @@
xmlns:vm="using:FRESHMusicPlayer.ViewModels" xmlns:vm="using:FRESHMusicPlayer.ViewModels"
mc:Ignorable="d" Width="500" Height="400" mc:Ignorable="d" Width="500" Height="400"
xmlns:svg="clr-namespace:Avalonia.Svg.Skia;assembly=Avalonia.Svg.Skia" xmlns:svg="clr-namespace:Avalonia.Svg.Skia;assembly=Avalonia.Svg.Skia"
x:Class="FRESHMusicPlayer.Views.QueueManagement" x:Class="FRESHMusicPlayer.Views.QueueManagement" Closing="OnClosing"
Title="QueueManagement"> Title="QueueManagement">
<Window.DataContext> <Window.DataContext>
<vm:QueueManagementViewModel/> <vm:QueueManagementViewModel/>
@ -21,11 +21,11 @@
<RowDefinition Height="1*"/> <RowDefinition Height="1*"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<StackPanel Grid.Column="0" Grid.Row="0" Orientation="Horizontal" Margin="5,5,5,0"> <DockPanel Grid.Column="0" Grid.Row="0" Margin="5,5,5,0">
<CheckBox Grid.Column="0" Grid.Row="0" IsChecked="{Binding $parent[Window].Topmost}" Content="Pin to top"/> <CheckBox DockPanel.Dock="Left" IsChecked="{Binding $parent[Window].Topmost}" Content="Pin to top"/>
<TextBlock Text="Time Remaining:" VerticalAlignment="Center"/> <TextBlock DockPanel.Dock="Right" Text="{Binding TimeRemaining, StringFormat=\{0:hh\\:mm\\:ss\}}" Margin="5,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Right"/>
<TextBlock Text="{Binding TimeRemaining, StringFormat=\{0:hh\\:mm\\:ss\}}" VerticalAlignment="Center"/> <TextBlock DockPanel.Dock="Right" Text="Time Remaining:" VerticalAlignment="Center" HorizontalAlignment="Right"/>
</StackPanel> </DockPanel>
<ListBox Grid.Column="0" Grid.Row="1" Items="{Binding Queue}" Margin="5,0,5,5" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectionMode="AlwaysSelected" VirtualizationMode="Simple" Focusable="False"> <ListBox Grid.Column="0" Grid.Row="1" Items="{Binding Queue}" Margin="5,0,5,5" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectionMode="AlwaysSelected" VirtualizationMode="Simple" Focusable="False">
@ -37,7 +37,7 @@
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/> <ColumnDefinition/>
<ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
@ -48,10 +48,10 @@
<TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding Title}" HorizontalAlignment="Stretch" TextTrimming="CharacterEllipsis" FontSize="15" FontWeight="Bold"/> <TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding Title}" HorizontalAlignment="Stretch" TextTrimming="CharacterEllipsis" FontSize="15" FontWeight="Bold"/>
<TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding Artist}" FontSize="10"/> <TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding Artist}" FontSize="10"/>
<StackPanel Grid.Column="2" Grid.RowSpan="2" VerticalAlignment="Center" Height="38" Margin="0,-27,0,-30" Orientation="Horizontal"> <StackPanel Grid.Column="2" Grid.RowSpan="2" VerticalAlignment="Center" Height="38" Margin="0,-27,0,-30" Orientation="Horizontal">
<Button IsVisible="{Binding $parent[1].IsPointerOver}" Command="{Binding JumpToCommand}" CommandParameter="{Binding Position}" VerticalAlignment="Center"> <Button IsVisible="{Binding $parent[1].IsPointerOver}" Click="OnJumpToButtonClick" VerticalAlignment="Center">
<Image Source="{DynamicResource Play}"/> <Image Source="{DynamicResource Play}"/>
</Button> </Button>
<Button IsVisible="{Binding $parent[1].IsPointerOver}" Command="{Binding RemoveCommand}" CommandParameter="{Binding Position}" VerticalAlignment="Center"> <Button IsVisible="{Binding $parent[1].IsPointerOver}" Click="OnRemoveButtonClick" VerticalAlignment="Center">
<Image Source="{DynamicResource Delete}"/> <Image Source="{DynamicResource Delete}"/>
</Button> </Button>
</StackPanel> </StackPanel>

View file

@ -1,14 +1,18 @@
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using FRESHMusicPlayer.Handlers; using FRESHMusicPlayer.Handlers;
using FRESHMusicPlayer.ViewModels; using FRESHMusicPlayer.ViewModels;
using System.ComponentModel;
using System.Timers; using System.Timers;
namespace FRESHMusicPlayer.Views namespace FRESHMusicPlayer.Views
{ {
public class QueueManagement : Window public class QueueManagement : Window
{ {
private QueueManagementViewModel ViewModel { get => DataContext as QueueManagementViewModel; }
public QueueManagement() public QueueManagement()
{ {
InitializeComponent(); InitializeComponent();
@ -31,5 +35,28 @@ namespace FRESHMusicPlayer.Views
context.StartThings(); context.StartThings();
return this; return this;
} }
private void OnJumpToButtonClick(object sender, RoutedEventArgs e)
{
var cmd = (Button)sender;
if (cmd.DataContext is QueueManagementEntry x)
{
ViewModel?.JumpToCommand(x.Position);
}
}
private void OnRemoveButtonClick(object sender, RoutedEventArgs e)
{
var cmd = (Button)sender;
if (cmd.DataContext is QueueManagementEntry x)
{
ViewModel?.RemoveCommand(x.Position);
}
}
private void OnClosing(object sender, CancelEventArgs e)
{
ViewModel?.CloseThings();
}
} }
} }