diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..834e311e
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,7 @@
+# These are supported funding model platforms
+
+github: difegue
+patreon: # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: lanraragi
+tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
index 794332e2..8ff558de 100644
--- a/.github/workflows/build-and-test.yml
+++ b/.github/workflows/build-and-test.yml
@@ -51,9 +51,9 @@ jobs:
# https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on
env:
- Solution_Name: MpcNET
- Uap_Project_Path: FluentMPC\FluentMPC.csproj
- Uap_Project_Directory: FluentMPC
+ Solution_Name: Stylophone
+ Uap_Project_Path: Stylophone\Stylophone.csproj
+ Uap_Project_Directory: Stylophone
steps:
- name: Checkout
@@ -76,9 +76,9 @@ jobs:
# Execute all unit tests in the solution
# TODO: This only runs the tests for MpcNET right now, since it's .NET Standard-based. Running the UWP tests would be nice too.
- - name: Execute unit tests
- working-directory: ./Sources
- run: dotnet test
+ #- name: Execute unit tests
+ # working-directory: ./Sources
+ # run: dotnet test
# Decode the base 64 encoded pfx and save the Signing_Certificate
- name: Decode the pfx
diff --git a/.gitignore b/.gitignore
index 4fb28247..588c486d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,36 +1,36 @@
-################################################################################
-# This .gitignore file was automatically created by Microsoft(R) Visual Studio.
-################################################################################
-
-/src/.vs
-
-/src/MpcNET/bin
-/src/MpcNET/obj
-
-/src/MpcNET.Test/bin
-/src/MpcNET.Test/obj
-
-
-/src/MpcNET.sln.DotSettings.user
-/src/MpcNET.Test/MpcNET.Test.csproj.DotSettings
-/src/MpcNET/MpcNET.csproj.DotSettings
-/.vs
-*.user
-/Sources/.vs/MpcNET/v15
-/Sources/MpcNET/bin/Debug/netstandard2.0
+################################################################################
+# This .gitignore file was automatically created by Microsoft(R) Visual Studio.
+################################################################################
+
+/Sources/.vs
+/Sources/MpcNET.sln.DotSettings.user
+
+/Sources/MpcNET/bin
/Sources/MpcNET/obj
+
+/Sources/MpcNET/MpcNET.csproj.DotSettings
+
+/Sources/MpcNET.Test/bin
/Sources/MpcNET.Test/obj
-/Sources/MpcNET/bin
-/Sources/MpcNET.Test/bin/Debug/netcoreapp2.0
-/Sources/.vs
-/Sources/FluentMPC.Core/bin/Debug/netstandard2.0
-/Sources/FluentMPC/bin/x86/Debug
-/Sources/FluentMPC/obj
-/Sources/FluentMPC.Core/obj
-/Sources/FluentMPC.Tests.MSTest/obj
+/Sources/MpcNET.Test/MpcNET.Test.csproj.DotSettings
+
+/Sources/Stylophone/bin
+/Sources/Stylophone/obj
+/Sources/Stylophone/Package.StoreAssociation.xml
+/Sources/Stylophone/AppPackages
+/Sources/Stylophone/BundleArtifacts
+
+/Sources/Stylophone.Common/bin
+/Sources/Stylophone.Common/obj
+
+/Sources/Stylophone.Localization/bin
+/Sources/Stylophone.Localization/obj
+
+
+/.vs
+*.user
*.pfx
-/Sources/FluentMPC/bin/x64/Debug
-/Sources/FluentMPC/Package.StoreAssociation.xml
-/Sources/FluentMPC/AppPackages
-/Sources/FluentMPC/bin
-/Sources/FluentMPC/BundleArtifacts
+Sources/.DS_Store
+Sources/Stylophone.iOS/bin
+Sources/Stylophone.iOS/obj
+.DS_Store
diff --git a/README.md b/README.md
index 5ac9c1d8..2bfc1ae9 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-
+
Stylophone
===========
@@ -8,6 +8,8 @@ Based on [MpcNET](https://github.com/petrkr/MpcNET), the original .NET Client Li
+[Buy a sticker if you want!](https://ko-fi.com/s/9fcf421b6e)
+
## Features
* Full playback control
@@ -37,16 +39,15 @@ You can easily contribute translations to Stylophone! To help translate, follow
- If an issue already exists, then don't do this step.
- Fork and clone this repo
- Open in VS 2019
-- In the `FluentMPC` project, find the `Strings` folder.
-- Create a new folder inside `Strings` that looks like this: `en-US` but using the language you're translating into.
-- Add a new `Resources.resw` item in that new folder
-- Copy all the existing data from `Strings > en-US` into your new `Resources.resw`
+- In the `Stylophone.Localization` project, find the `Strings` folder.
+- Create a new file inside `Strings` that looks like this: `Resources.en-US.resx` but using the language you're translating into.
+- Copy all the existing data from `Resources.en-US.resx` into your new `Resources.[language].resx`
- Translate the strings from english to your language
- Once done, then commit > push > create pull request!
### Improving an existing language (can be done with any text editor)
- Fork and clone this repo
-- Open the the `.resw` file (e.g. `en-US > Resources.resw`) you want to edit. Choose any text editor
+- Open the `.resx` file (e.g. `Resources.en-US.resx`) you want to edit. Choose any text editor
- Translate
- Commit > push > create pull request!
@@ -61,5 +62,8 @@ You can easily contribute translations to Stylophone! To help translate, follow
## Privacy Policy
-Stylophone collects no data from your computer.
+Stylophone collects no data from your computer by default.
The Windows Store version can send anonymized error reports related to crashes of the application back to me.
+
+If you enable Telemetry in the app's settings, the application will send detailed crash reports using App Center.
+Those reports can contain information about your hardware. (Motherboard type, etc)
diff --git a/Screenshots/Screen1.jpg b/Screenshots/Screen1.jpg
index 92966365..99d6c21f 100644
Binary files a/Screenshots/Screen1.jpg and b/Screenshots/Screen1.jpg differ
diff --git a/Screenshots/Screen2.jpg b/Screenshots/Screen2.jpg
index 1317537f..536e063c 100644
Binary files a/Screenshots/Screen2.jpg and b/Screenshots/Screen2.jpg differ
diff --git a/Screenshots/Screen3.jpg b/Screenshots/Screen3.jpg
index 50049855..3a1e5bad 100644
Binary files a/Screenshots/Screen3.jpg and b/Screenshots/Screen3.jpg differ
diff --git a/Screenshots/Screen4.jpg b/Screenshots/Screen4.jpg
index ba2216df..e62a5d67 100644
Binary files a/Screenshots/Screen4.jpg and b/Screenshots/Screen4.jpg differ
diff --git a/Screenshots/Screen5.jpg b/Screenshots/Screen5.jpg
index 771e85a1..07ebf063 100644
Binary files a/Screenshots/Screen5.jpg and b/Screenshots/Screen5.jpg differ
diff --git a/Screenshots/Screen6.jpg b/Screenshots/Screen6.jpg
index c32db99d..5641063a 100644
Binary files a/Screenshots/Screen6.jpg and b/Screenshots/Screen6.jpg differ
diff --git a/Screenshots/ScreenXbox.jpg b/Screenshots/ScreenXbox.jpg
index a0b29793..0360c8cb 100644
Binary files a/Screenshots/ScreenXbox.jpg and b/Screenshots/ScreenXbox.jpg differ
diff --git a/Sources/.vs/MpcNET/DesignTimeBuild/.dtbcache b/Sources/.vs/MpcNET/DesignTimeBuild/.dtbcache
deleted file mode 100644
index 17d54e23..00000000
Binary files a/Sources/.vs/MpcNET/DesignTimeBuild/.dtbcache and /dev/null differ
diff --git a/Sources/FluentMPC.Tests.MSTest/Assets/LockScreenLogo.scale-200.png b/Sources/FluentMPC.Tests.MSTest/Assets/LockScreenLogo.scale-200.png
deleted file mode 100644
index 735f57ad..00000000
Binary files a/Sources/FluentMPC.Tests.MSTest/Assets/LockScreenLogo.scale-200.png and /dev/null differ
diff --git a/Sources/FluentMPC.Tests.MSTest/Assets/SplashScreen.scale-200.png b/Sources/FluentMPC.Tests.MSTest/Assets/SplashScreen.scale-200.png
deleted file mode 100644
index 023e7f1f..00000000
Binary files a/Sources/FluentMPC.Tests.MSTest/Assets/SplashScreen.scale-200.png and /dev/null differ
diff --git a/Sources/FluentMPC.Tests.MSTest/Assets/Square150x150Logo.scale-200.png b/Sources/FluentMPC.Tests.MSTest/Assets/Square150x150Logo.scale-200.png
deleted file mode 100644
index af49fec1..00000000
Binary files a/Sources/FluentMPC.Tests.MSTest/Assets/Square150x150Logo.scale-200.png and /dev/null differ
diff --git a/Sources/FluentMPC.Tests.MSTest/Assets/Square44x44Logo.scale-200.png b/Sources/FluentMPC.Tests.MSTest/Assets/Square44x44Logo.scale-200.png
deleted file mode 100644
index ce342a2e..00000000
Binary files a/Sources/FluentMPC.Tests.MSTest/Assets/Square44x44Logo.scale-200.png and /dev/null differ
diff --git a/Sources/FluentMPC.Tests.MSTest/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/Sources/FluentMPC.Tests.MSTest/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
deleted file mode 100644
index f6c02ce9..00000000
Binary files a/Sources/FluentMPC.Tests.MSTest/Assets/Square44x44Logo.targetsize-24_altform-unplated.png and /dev/null differ
diff --git a/Sources/FluentMPC.Tests.MSTest/Assets/StoreLogo.png b/Sources/FluentMPC.Tests.MSTest/Assets/StoreLogo.png
deleted file mode 100644
index 7385b56c..00000000
Binary files a/Sources/FluentMPC.Tests.MSTest/Assets/StoreLogo.png and /dev/null differ
diff --git a/Sources/FluentMPC.Tests.MSTest/Assets/Wide310x150Logo.scale-200.png b/Sources/FluentMPC.Tests.MSTest/Assets/Wide310x150Logo.scale-200.png
deleted file mode 100644
index 288995b3..00000000
Binary files a/Sources/FluentMPC.Tests.MSTest/Assets/Wide310x150Logo.scale-200.png and /dev/null differ
diff --git a/Sources/FluentMPC.Tests.MSTest/FluentMPC.Tests.MSTest.csproj b/Sources/FluentMPC.Tests.MSTest/FluentMPC.Tests.MSTest.csproj
deleted file mode 100644
index c03f4734..00000000
--- a/Sources/FluentMPC.Tests.MSTest/FluentMPC.Tests.MSTest.csproj
+++ /dev/null
@@ -1,162 +0,0 @@
-
-
-
-
- Debug
- x86
- {0C4B7830-1CAE-4EDC-BF92-526A50424157}
- AppContainerExe
- Properties
- FluentMPC.Tests.MSTest
- FluentMPC.Tests.MSTest
- en-US
- UAP
- 10.0.19041.0
- 10.0.18362.0
- 14
- 512
- {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- FluentMPC.Tests.MSTest_TemporaryKey.pfx
- $(VisualStudioVersion)
-
-
- true
- bin\x86\Debug\
- DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
- ;2008
- full
- x86
- false
- prompt
- true
-
-
- bin\x86\Release\
- TRACE;NETFX_CORE;WINDOWS_UWP
- true
- ;2008
- pdbonly
- x86
- false
- prompt
- true
- true
-
-
- true
- bin\ARM\Debug\
- DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
- ;2008
- full
- ARM
- false
- prompt
- true
-
-
- bin\ARM\Release\
- TRACE;NETFX_CORE;WINDOWS_UWP
- true
- ;2008
- pdbonly
- ARM
- false
- prompt
- true
- true
-
-
- true
- bin\x64\Debug\
- DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
- ;2008
- full
- x64
- false
- prompt
- true
-
-
- bin\x64\Release\
- TRACE;NETFX_CORE;WINDOWS_UWP
- true
- ;2008
- pdbonly
- x64
- false
- prompt
- true
- true
-
-
- PackageReference
-
-
-
- 6.2.9
-
-
- 2.4.2
-
-
- 2.0.1
-
-
- 2.1.2
-
-
- 2.1.2
-
-
-
-
-
-
-
-
- UnitTestApp.xaml
-
-
-
-
-
- MSBuild:Compile
- Designer
-
-
-
-
- Designer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {5A5CE693-A67D-4B28-8DCE-4B0EA3A47533}
- FluentMPC
-
-
-
- 14.0
-
-
-
-
\ No newline at end of file
diff --git a/Sources/FluentMPC.Tests.MSTest/Package.appxmanifest b/Sources/FluentMPC.Tests.MSTest/Package.appxmanifest
deleted file mode 100644
index 5ee97965..00000000
--- a/Sources/FluentMPC.Tests.MSTest/Package.appxmanifest
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
-
-
-
-
- FluentMPC.Tests.MSTest
- Vincent
- Assets\StoreLogo.png
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Sources/FluentMPC.Tests.MSTest/Properties/AssemblyInfo.cs b/Sources/FluentMPC.Tests.MSTest/Properties/AssemblyInfo.cs
deleted file mode 100644
index 5ccae4ca..00000000
--- a/Sources/FluentMPC.Tests.MSTest/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-[assembly: AssemblyTitle("FluentMPC.Tests.MSTest")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("FluentMPC.Tests.MSTest")]
-[assembly: AssemblyCopyright("Copyright © 2020")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: AssemblyMetadata("TargetPlatform", "UAP")]
-
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
-[assembly: ComVisible(false)]
diff --git a/Sources/FluentMPC.Tests.MSTest/Properties/UnitTestApp.rd.xml b/Sources/FluentMPC.Tests.MSTest/Properties/UnitTestApp.rd.xml
deleted file mode 100644
index 8f1b21b4..00000000
--- a/Sources/FluentMPC.Tests.MSTest/Properties/UnitTestApp.rd.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Sources/FluentMPC.Tests.MSTest/Tests.cs b/Sources/FluentMPC.Tests.MSTest/Tests.cs
deleted file mode 100644
index f979f309..00000000
--- a/Sources/FluentMPC.Tests.MSTest/Tests.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using System;
-
-using FluentMPC.ViewModels;
-using FluentMPC.ViewModels.Playback;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-namespace FluentMPC.Tests.MSTest
-{
- // TODO WTS: Add appropriate tests
- [TestClass]
- public class Tests
- {
- [TestMethod]
- public void TestMethod1()
- {
- }
-
- // TODO WTS: Add tests for functionality you add to FoldersViewModel.
- [TestMethod]
- public void TestFoldersViewModelCreation()
- {
- // This test is trivial. Add your own tests for the logic you add to the ViewModel.
- var vm = new FoldersViewModel();
- Assert.IsNotNull(vm);
- }
-
- // TODO WTS: Add tests for functionality you add to LibraryViewModel.
- [TestMethod]
- public void TestLibraryViewModelCreation()
- {
- // This test is trivial. Add your own tests for the logic you add to the ViewModel.
- var vm = new LibraryViewModel();
- Assert.IsNotNull(vm);
- }
-
- // TODO WTS: Add tests for functionality you add to NowPlayingViewModel.
- [TestMethod]
- public void TestNowPlayingViewModelCreation()
- {
- // This test is trivial. Add your own tests for the logic you add to the ViewModel.
- var vm = new PlaybackViewModel();
- Assert.IsNotNull(vm);
- }
-
- // TODO WTS: Add tests for functionality you add to PlaylistsViewModel.
- [TestMethod]
- public void TestPlaylistsViewModelCreation()
- {
- // This test is trivial. Add your own tests for the logic you add to the ViewModel.
- var vm = new PlaylistViewModel();
- Assert.IsNotNull(vm);
- }
-
- // TODO WTS: Add tests for functionality you add to SettingsViewModel.
- [TestMethod]
- public void TestSettingsViewModelCreation()
- {
- // This test is trivial. Add your own tests for the logic you add to the ViewModel.
- var vm = new SettingsViewModel();
- Assert.IsNotNull(vm);
- }
- }
-}
diff --git a/Sources/FluentMPC.Tests.MSTest/UnitTestApp.xaml b/Sources/FluentMPC.Tests.MSTest/UnitTestApp.xaml
deleted file mode 100644
index b95cf77d..00000000
--- a/Sources/FluentMPC.Tests.MSTest/UnitTestApp.xaml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Sources/FluentMPC.Tests.MSTest/UnitTestApp.xaml.cs b/Sources/FluentMPC.Tests.MSTest/UnitTestApp.xaml.cs
deleted file mode 100644
index 94055a34..00000000
--- a/Sources/FluentMPC.Tests.MSTest/UnitTestApp.xaml.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Runtime.InteropServices.WindowsRuntime;
-
-using Windows.ApplicationModel;
-using Windows.ApplicationModel.Activation;
-using Windows.Foundation;
-using Windows.Foundation.Collections;
-using Windows.UI.Xaml;
-using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Controls.Primitives;
-using Windows.UI.Xaml.Data;
-using Windows.UI.Xaml.Input;
-using Windows.UI.Xaml.Media;
-using Windows.UI.Xaml.Navigation;
-
-namespace FluentMPC.Tests.MSTest
-{
- public sealed partial class App : Application
- {
- public App()
- {
- InitializeComponent();
- Suspending += OnSuspending;
- }
-
- protected override void OnLaunched(LaunchActivatedEventArgs e)
- {
-#if DEBUG
- if (System.Diagnostics.Debugger.IsAttached)
- {
- DebugSettings.EnableFrameRateCounter = true;
- }
-#endif
-
- Frame rootFrame = Window.Current.Content as Frame;
-
- // Do not repeat app initialization when the Window already has content,
- // just ensure that the window is active
- if (rootFrame == null)
- {
- // Create a Frame to act as the navigation context and navigate to the first page
- rootFrame = new Frame();
-
- rootFrame.NavigationFailed += OnNavigationFailed;
-
- if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
- {
- // In a regular app, this is where you would
- // Load state from previously suspended application
- // But this should not be necessary in a test app
- }
-
- // Place the frame in the current Window
- Window.Current.Content = rootFrame;
- }
-
- Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.CreateDefaultUI();
-
- // Ensure the current window is active
- Window.Current.Activate();
-
- Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.Run(e.Arguments);
- }
-
- private void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
- {
- throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
- }
-
- private void OnSuspending(object sender, SuspendingEventArgs e)
- {
- var deferral = e.SuspendingOperation.GetDeferral();
-
- // In a regular app, this is where you would
- // Save application state and stop any background activity
- // But this should not be necessary in a test app
- deferral.Complete();
- }
- }
-
- // This type is defined to force the compiler to add the necessary references and allows tests to run
- public class WinUiReference : Windows.UI.Xaml.Controls.Button
- {
- }
-}
diff --git a/Sources/FluentMPC/App.xaml b/Sources/FluentMPC/App.xaml
deleted file mode 100644
index dc694fd2..00000000
--- a/Sources/FluentMPC/App.xaml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Sources/FluentMPC/App.xaml.cs b/Sources/FluentMPC/App.xaml.cs
deleted file mode 100644
index 81d306d4..00000000
--- a/Sources/FluentMPC/App.xaml.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-using System;
-using FluentMPC.Helpers;
-using FluentMPC.Services;
-
-using Windows.ApplicationModel.Activation;
-using Windows.Storage;
-using Windows.UI;
-using Windows.UI.ViewManagement;
-using Windows.UI.Xaml;
-
-namespace FluentMPC
-{
- public sealed partial class App : Application
- {
- private Lazy _activationService;
-
- private ActivationService ActivationService
- {
- get { return _activationService.Value; }
- }
-
- public App()
- {
- InitializeComponent();
-
- // Deferred execution until used. Check https://msdn.microsoft.com/library/dd642331(v=vs.110).aspx for further info on Lazy class.
- _activationService = new Lazy(CreateActivationService);
- }
-
- protected override async void OnLaunched(LaunchActivatedEventArgs args)
- {
- Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
- Windows.ApplicationModel.Core.CoreApplication.EnablePrelaunch(true);
-
- // https://docs.microsoft.com/en-us/windows/uwp/design/devices/designing-for-tv#custom-visual-state-trigger-for-xbox
- ApplicationView.GetForCurrentView().SetDesiredBoundsMode(ApplicationViewBoundsMode.UseCoreWindow);
-
- // Compact sizing
- var isCompactEnabled = await ApplicationData.Current.LocalSettings.ReadAsync("IsCompactSizing");
- if (isCompactEnabled)
- {
- Resources.MergedDictionaries.Add(
- new ResourceDictionary { Source = new Uri(@"ms-appx:///Microsoft.UI.Xaml/DensityStyles/Compact.xaml", UriKind.Absolute) });
- }
-
- var viewTitleBar = ApplicationView.GetForCurrentView().TitleBar;
- viewTitleBar.ButtonBackgroundColor = Colors.Transparent;
- viewTitleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
- viewTitleBar.ButtonForegroundColor = (Color)Resources["SystemBaseHighColor"];
- viewTitleBar.ButtonInactiveForegroundColor = (Color)Resources["SystemBaseHighColor"];
-
- if (!args.PrelaunchActivated)
- {
- await ActivationService.ActivateAsync(args);
- }
- }
-
- protected override async void OnActivated(IActivatedEventArgs args)
- {
- await ActivationService.ActivateAsync(args);
- }
-
- private ActivationService CreateActivationService()
- {
- return new ActivationService(this, typeof(Views.ServerQueuePage), new Lazy(CreateShell));
- }
-
- private UIElement CreateShell()
- {
- return new Views.ShellPage();
- }
-
- protected override async void OnBackgroundActivated(BackgroundActivatedEventArgs args)
- {
- await ActivationService.ActivateAsync(args);
- }
- }
-}
diff --git a/Sources/FluentMPC/Assets/AlbumPlaceholder.png b/Sources/FluentMPC/Assets/AlbumPlaceholder.png
deleted file mode 100644
index 6d1338ac..00000000
Binary files a/Sources/FluentMPC/Assets/AlbumPlaceholder.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/LargeTile.scale-100.png b/Sources/FluentMPC/Assets/LargeTile.scale-100.png
deleted file mode 100644
index 9a9bcdc0..00000000
Binary files a/Sources/FluentMPC/Assets/LargeTile.scale-100.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/LargeTile.scale-125.png b/Sources/FluentMPC/Assets/LargeTile.scale-125.png
deleted file mode 100644
index 065f191c..00000000
Binary files a/Sources/FluentMPC/Assets/LargeTile.scale-125.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/LargeTile.scale-150.png b/Sources/FluentMPC/Assets/LargeTile.scale-150.png
deleted file mode 100644
index b48cc852..00000000
Binary files a/Sources/FluentMPC/Assets/LargeTile.scale-150.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/LargeTile.scale-200.png b/Sources/FluentMPC/Assets/LargeTile.scale-200.png
deleted file mode 100644
index 123aa387..00000000
Binary files a/Sources/FluentMPC/Assets/LargeTile.scale-200.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/LargeTile.scale-400.png b/Sources/FluentMPC/Assets/LargeTile.scale-400.png
deleted file mode 100644
index 93b85abb..00000000
Binary files a/Sources/FluentMPC/Assets/LargeTile.scale-400.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/SmallTile.scale-100.png b/Sources/FluentMPC/Assets/SmallTile.scale-100.png
deleted file mode 100644
index 4100b88f..00000000
Binary files a/Sources/FluentMPC/Assets/SmallTile.scale-100.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/SmallTile.scale-125.png b/Sources/FluentMPC/Assets/SmallTile.scale-125.png
deleted file mode 100644
index 9ee30f37..00000000
Binary files a/Sources/FluentMPC/Assets/SmallTile.scale-125.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/SmallTile.scale-150.png b/Sources/FluentMPC/Assets/SmallTile.scale-150.png
deleted file mode 100644
index 61bc4152..00000000
Binary files a/Sources/FluentMPC/Assets/SmallTile.scale-150.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/SmallTile.scale-200.png b/Sources/FluentMPC/Assets/SmallTile.scale-200.png
deleted file mode 100644
index 4b8e7977..00000000
Binary files a/Sources/FluentMPC/Assets/SmallTile.scale-200.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/SmallTile.scale-400.png b/Sources/FluentMPC/Assets/SmallTile.scale-400.png
deleted file mode 100644
index 27ed37b3..00000000
Binary files a/Sources/FluentMPC/Assets/SmallTile.scale-400.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/SplashScreen.scale-100.png b/Sources/FluentMPC/Assets/SplashScreen.scale-100.png
deleted file mode 100644
index 64cd648f..00000000
Binary files a/Sources/FluentMPC/Assets/SplashScreen.scale-100.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/SplashScreen.scale-125.png b/Sources/FluentMPC/Assets/SplashScreen.scale-125.png
deleted file mode 100644
index 005f889f..00000000
Binary files a/Sources/FluentMPC/Assets/SplashScreen.scale-125.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/SplashScreen.scale-150.png b/Sources/FluentMPC/Assets/SplashScreen.scale-150.png
deleted file mode 100644
index 4ef6b8ab..00000000
Binary files a/Sources/FluentMPC/Assets/SplashScreen.scale-150.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/SplashScreen.scale-200.png b/Sources/FluentMPC/Assets/SplashScreen.scale-200.png
deleted file mode 100644
index 81b01a6b..00000000
Binary files a/Sources/FluentMPC/Assets/SplashScreen.scale-200.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/SplashScreen.scale-400.png b/Sources/FluentMPC/Assets/SplashScreen.scale-400.png
deleted file mode 100644
index 7dce50d2..00000000
Binary files a/Sources/FluentMPC/Assets/SplashScreen.scale-400.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square150x150Logo.scale-100.png b/Sources/FluentMPC/Assets/Square150x150Logo.scale-100.png
deleted file mode 100644
index 7903c5d9..00000000
Binary files a/Sources/FluentMPC/Assets/Square150x150Logo.scale-100.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square150x150Logo.scale-125.png b/Sources/FluentMPC/Assets/Square150x150Logo.scale-125.png
deleted file mode 100644
index 34e10a26..00000000
Binary files a/Sources/FluentMPC/Assets/Square150x150Logo.scale-125.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square150x150Logo.scale-150.png b/Sources/FluentMPC/Assets/Square150x150Logo.scale-150.png
deleted file mode 100644
index 2693e1d7..00000000
Binary files a/Sources/FluentMPC/Assets/Square150x150Logo.scale-150.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square150x150Logo.scale-200.png b/Sources/FluentMPC/Assets/Square150x150Logo.scale-200.png
deleted file mode 100644
index d2d7e2a9..00000000
Binary files a/Sources/FluentMPC/Assets/Square150x150Logo.scale-200.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square150x150Logo.scale-400.png b/Sources/FluentMPC/Assets/Square150x150Logo.scale-400.png
deleted file mode 100644
index f43d7d9b..00000000
Binary files a/Sources/FluentMPC/Assets/Square150x150Logo.scale-400.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.altform-lightunplated_targetsize-16.png b/Sources/FluentMPC/Assets/Square44x44Logo.altform-lightunplated_targetsize-16.png
deleted file mode 100644
index 34d56f1e..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.altform-lightunplated_targetsize-16.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.altform-lightunplated_targetsize-24.png b/Sources/FluentMPC/Assets/Square44x44Logo.altform-lightunplated_targetsize-24.png
deleted file mode 100644
index 10823321..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.altform-lightunplated_targetsize-24.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png b/Sources/FluentMPC/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png
deleted file mode 100644
index 960201b1..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.altform-lightunplated_targetsize-32.png b/Sources/FluentMPC/Assets/Square44x44Logo.altform-lightunplated_targetsize-32.png
deleted file mode 100644
index 6f6ac3f1..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.altform-lightunplated_targetsize-32.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.altform-lightunplated_targetsize-48.png b/Sources/FluentMPC/Assets/Square44x44Logo.altform-lightunplated_targetsize-48.png
deleted file mode 100644
index cb4b417a..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.altform-lightunplated_targetsize-48.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.altform-unplated_targetsize-16.png b/Sources/FluentMPC/Assets/Square44x44Logo.altform-unplated_targetsize-16.png
deleted file mode 100644
index 34d56f1e..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.altform-unplated_targetsize-16.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.altform-unplated_targetsize-256.png b/Sources/FluentMPC/Assets/Square44x44Logo.altform-unplated_targetsize-256.png
deleted file mode 100644
index 960201b1..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.altform-unplated_targetsize-256.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.altform-unplated_targetsize-32.png b/Sources/FluentMPC/Assets/Square44x44Logo.altform-unplated_targetsize-32.png
deleted file mode 100644
index 6f6ac3f1..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.altform-unplated_targetsize-32.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.altform-unplated_targetsize-48.png b/Sources/FluentMPC/Assets/Square44x44Logo.altform-unplated_targetsize-48.png
deleted file mode 100644
index cb4b417a..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.altform-unplated_targetsize-48.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.scale-100.png b/Sources/FluentMPC/Assets/Square44x44Logo.scale-100.png
deleted file mode 100644
index 39b4bdde..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.scale-100.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.scale-125.png b/Sources/FluentMPC/Assets/Square44x44Logo.scale-125.png
deleted file mode 100644
index dc04c8ec..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.scale-125.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.scale-150.png b/Sources/FluentMPC/Assets/Square44x44Logo.scale-150.png
deleted file mode 100644
index 0d5a4e15..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.scale-150.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.scale-200.png b/Sources/FluentMPC/Assets/Square44x44Logo.scale-200.png
deleted file mode 100644
index 06869ba1..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.scale-200.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.scale-400.png b/Sources/FluentMPC/Assets/Square44x44Logo.scale-400.png
deleted file mode 100644
index 9caaabd4..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.scale-400.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.targetsize-16.png b/Sources/FluentMPC/Assets/Square44x44Logo.targetsize-16.png
deleted file mode 100644
index 1cd219f5..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.targetsize-16.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.targetsize-24.png b/Sources/FluentMPC/Assets/Square44x44Logo.targetsize-24.png
deleted file mode 100644
index 94787ad8..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.targetsize-24.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/Sources/FluentMPC/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
deleted file mode 100644
index 10823321..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.targetsize-24_altform-unplated.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.targetsize-256.png b/Sources/FluentMPC/Assets/Square44x44Logo.targetsize-256.png
deleted file mode 100644
index f44af681..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.targetsize-256.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.targetsize-32.png b/Sources/FluentMPC/Assets/Square44x44Logo.targetsize-32.png
deleted file mode 100644
index d30fb0a5..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.targetsize-32.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Square44x44Logo.targetsize-48.png b/Sources/FluentMPC/Assets/Square44x44Logo.targetsize-48.png
deleted file mode 100644
index 8541624b..00000000
Binary files a/Sources/FluentMPC/Assets/Square44x44Logo.targetsize-48.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/StoreLogo.scale-100.png b/Sources/FluentMPC/Assets/StoreLogo.scale-100.png
deleted file mode 100644
index a1c1a347..00000000
Binary files a/Sources/FluentMPC/Assets/StoreLogo.scale-100.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/StoreLogo.scale-125.png b/Sources/FluentMPC/Assets/StoreLogo.scale-125.png
deleted file mode 100644
index ace2735a..00000000
Binary files a/Sources/FluentMPC/Assets/StoreLogo.scale-125.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/StoreLogo.scale-150.png b/Sources/FluentMPC/Assets/StoreLogo.scale-150.png
deleted file mode 100644
index f0f35f5d..00000000
Binary files a/Sources/FluentMPC/Assets/StoreLogo.scale-150.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/StoreLogo.scale-200.png b/Sources/FluentMPC/Assets/StoreLogo.scale-200.png
deleted file mode 100644
index 0b6a0e0f..00000000
Binary files a/Sources/FluentMPC/Assets/StoreLogo.scale-200.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/StoreLogo.scale-400.png b/Sources/FluentMPC/Assets/StoreLogo.scale-400.png
deleted file mode 100644
index f68bfcd8..00000000
Binary files a/Sources/FluentMPC/Assets/StoreLogo.scale-400.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Wide310x150Logo.scale-100.png b/Sources/FluentMPC/Assets/Wide310x150Logo.scale-100.png
deleted file mode 100644
index 48f38108..00000000
Binary files a/Sources/FluentMPC/Assets/Wide310x150Logo.scale-100.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Wide310x150Logo.scale-125.png b/Sources/FluentMPC/Assets/Wide310x150Logo.scale-125.png
deleted file mode 100644
index 449bf46e..00000000
Binary files a/Sources/FluentMPC/Assets/Wide310x150Logo.scale-125.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Wide310x150Logo.scale-150.png b/Sources/FluentMPC/Assets/Wide310x150Logo.scale-150.png
deleted file mode 100644
index 9c913614..00000000
Binary files a/Sources/FluentMPC/Assets/Wide310x150Logo.scale-150.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Wide310x150Logo.scale-200.png b/Sources/FluentMPC/Assets/Wide310x150Logo.scale-200.png
deleted file mode 100644
index 64cd648f..00000000
Binary files a/Sources/FluentMPC/Assets/Wide310x150Logo.scale-200.png and /dev/null differ
diff --git a/Sources/FluentMPC/Assets/Wide310x150Logo.scale-400.png b/Sources/FluentMPC/Assets/Wide310x150Logo.scale-400.png
deleted file mode 100644
index 81b01a6b..00000000
Binary files a/Sources/FluentMPC/Assets/Wide310x150Logo.scale-400.png and /dev/null differ
diff --git a/Sources/FluentMPC/BackgroundTasks/BackgroundTask.cs b/Sources/FluentMPC/BackgroundTasks/BackgroundTask.cs
deleted file mode 100644
index 15ef3e5f..00000000
--- a/Sources/FluentMPC/BackgroundTasks/BackgroundTask.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System;
-using System.Threading.Tasks;
-
-using Windows.ApplicationModel.Background;
-
-namespace FluentMPC.BackgroundTasks
-{
- public abstract class BackgroundTask
- {
- public abstract void Register();
-
- public abstract Task RunAsyncInternal(IBackgroundTaskInstance taskInstance);
-
- public abstract void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason);
-
- public bool Match(string name)
- {
- return name == GetType().Name;
- }
-
- public Task RunAsync(IBackgroundTaskInstance taskInstance)
- {
- SubscribeToEvents(taskInstance);
-
- return RunAsyncInternal(taskInstance);
- }
-
- public void SubscribeToEvents(IBackgroundTaskInstance taskInstance)
- {
- taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled);
- }
- }
-}
diff --git a/Sources/FluentMPC/BackgroundTasks/LiveTileUpdateTask.cs b/Sources/FluentMPC/BackgroundTasks/LiveTileUpdateTask.cs
deleted file mode 100644
index 12e0fecd..00000000
--- a/Sources/FluentMPC/BackgroundTasks/LiveTileUpdateTask.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-using FluentMPC.Helpers;
-using FluentMPC.Services;
-using System.Linq;
-using System.Threading.Tasks;
-
-using Windows.ApplicationModel.Background;
-
-namespace FluentMPC.BackgroundTasks
-{
- public sealed class LiveTileUpdateTask : BackgroundTask
- {
-
- private volatile bool _cancelRequested = false;
- private BackgroundTaskDeferral _deferral;
-
- public override void Register()
- {
- var taskName = GetType().Name;
- var taskRegistration = BackgroundTaskRegistration.AllTasks.FirstOrDefault(t => t.Value.Name == taskName).Value;
-
- if (taskRegistration == null)
- {
- var builder = new BackgroundTaskBuilder()
- {
- Name = taskName
- };
-
- builder.SetTrigger(new TimeTrigger(15, false));
- builder.AddCondition(new SystemCondition(SystemConditionType.UserPresent));
-
- builder.Register();
- }
- }
-
- public override Task RunAsyncInternal(IBackgroundTaskInstance taskInstance)
- {
- if (taskInstance == null)
- {
- return null;
- }
-
- _deferral = taskInstance.GetDeferral();
-
- return Task.Run(async () =>
- {
- //// Documentation:
- //// * General: https://docs.microsoft.com/windows/uwp/launch-resume/support-your-app-with-background-tasks
- //// * Debug: https://docs.microsoft.com/windows/uwp/launch-resume/debug-a-background-task
- //// * Monitoring: https://docs.microsoft.com/windows/uwp/launch-resume/monitor-background-task-progress-and-completion
-
- //// To show the background progress and message on any page in the application,
- //// subscribe to the Progress and Completed events.
- //// You can do this via "BackgroundTaskService.GetBackgroundTasksRegistration"
- try
- {
- if (_cancelRequested) return;
-
- var currentSong = await MPDConnectionService.GetCurrentSong();
- if (currentSong == null) return;
-
- Singleton.Instance.UpdatePlayingSong(new ViewModels.Items.TrackViewModel(currentSong));
- }
- catch
- {
- // Whatever, this background task isn't very useful tbh
- }
- finally
- {
- _deferral?.Complete();
- }
- });
- }
-
- public override void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
- {
- _cancelRequested = true;
- }
- }
-}
diff --git a/Sources/FluentMPC/Behaviors/NavigationViewHeaderBehavior.cs b/Sources/FluentMPC/Behaviors/NavigationViewHeaderBehavior.cs
deleted file mode 100644
index 21128820..00000000
--- a/Sources/FluentMPC/Behaviors/NavigationViewHeaderBehavior.cs
+++ /dev/null
@@ -1,135 +0,0 @@
-using FluentMPC.Services;
-
-using Microsoft.Xaml.Interactivity;
-
-using Windows.UI.Xaml;
-using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Navigation;
-
-using WinUI = Microsoft.UI.Xaml.Controls;
-
-namespace FluentMPC.Behaviors
-{
- public class NavigationViewHeaderBehavior : Behavior
- {
- private static NavigationViewHeaderBehavior _current;
- private Page _currentPage;
-
- public DataTemplate DefaultHeaderTemplate { get; set; }
-
- public object DefaultHeader
- {
- get { return GetValue(DefaultHeaderProperty); }
- set { SetValue(DefaultHeaderProperty, value); }
- }
-
- public static readonly DependencyProperty DefaultHeaderProperty = DependencyProperty.Register("DefaultHeader", typeof(object), typeof(NavigationViewHeaderBehavior), new PropertyMetadata(null, (d, e) => _current.UpdateHeader()));
-
- public static NavigationViewHeaderMode GetHeaderMode(Page item)
- {
- return (NavigationViewHeaderMode)item.GetValue(HeaderModeProperty);
- }
-
- public static void SetHeaderMode(Page item, NavigationViewHeaderMode value)
- {
- item.SetValue(HeaderModeProperty, value);
- }
-
- public static readonly DependencyProperty HeaderModeProperty =
- DependencyProperty.RegisterAttached("HeaderMode", typeof(bool), typeof(NavigationViewHeaderBehavior), new PropertyMetadata(NavigationViewHeaderMode.Always, (d, e) => _current.UpdateHeader()));
-
- public static object GetHeaderContext(Page item)
- {
- return item.GetValue(HeaderContextProperty);
- }
-
- public static void SetHeaderContext(Page item, object value)
- {
- item.SetValue(HeaderContextProperty, value);
- }
-
- public static readonly DependencyProperty HeaderContextProperty =
- DependencyProperty.RegisterAttached("HeaderContext", typeof(object), typeof(NavigationViewHeaderBehavior), new PropertyMetadata(null, (d, e) => _current.UpdateHeader()));
-
- public static DataTemplate GetHeaderTemplate(Page item)
- {
- return (DataTemplate)item.GetValue(HeaderTemplateProperty);
- }
-
- public static void SetHeaderTemplate(Page item, DataTemplate value)
- {
- item.SetValue(HeaderTemplateProperty, value);
- }
-
- public static readonly DependencyProperty HeaderTemplateProperty =
- DependencyProperty.RegisterAttached("HeaderTemplate", typeof(DataTemplate), typeof(NavigationViewHeaderBehavior), new PropertyMetadata(null, (d, e) => _current.UpdateHeaderTemplate()));
-
- protected override void OnAttached()
- {
- base.OnAttached();
- _current = this;
- NavigationService.Navigated += OnNavigated;
- }
-
- protected override void OnDetaching()
- {
- base.OnDetaching();
- NavigationService.Navigated -= OnNavigated;
- }
-
- private void OnNavigated(object sender, NavigationEventArgs e)
- {
- var frame = sender as Frame;
- if (frame.Content is Page page)
- {
- _currentPage = page;
-
- UpdateHeader();
- UpdateHeaderTemplate();
- }
- }
-
- private void UpdateHeader()
- {
- if (_currentPage != null)
- {
- var headerMode = GetHeaderMode(_currentPage);
- if (headerMode == NavigationViewHeaderMode.Never)
- {
- AssociatedObject.Header = null;
- AssociatedObject.AlwaysShowHeader = false;
- }
- else
- {
- var headerFromPage = GetHeaderContext(_currentPage);
- if (headerFromPage != null)
- {
- AssociatedObject.Header = headerFromPage;
- }
- else
- {
- AssociatedObject.Header = DefaultHeader;
- }
-
- if (headerMode == NavigationViewHeaderMode.Always)
- {
- AssociatedObject.AlwaysShowHeader = true;
- }
- else
- {
- AssociatedObject.AlwaysShowHeader = false;
- }
- }
- }
- }
-
- private void UpdateHeaderTemplate()
- {
- if (_currentPage != null)
- {
- var headerTemplate = GetHeaderTemplate(_currentPage);
- AssociatedObject.HeaderTemplate = headerTemplate ?? DefaultHeaderTemplate;
- }
- }
- }
-}
diff --git a/Sources/FluentMPC/Behaviors/NavigationViewHeaderMode.cs b/Sources/FluentMPC/Behaviors/NavigationViewHeaderMode.cs
deleted file mode 100644
index ccf1acfb..00000000
--- a/Sources/FluentMPC/Behaviors/NavigationViewHeaderMode.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace FluentMPC.Behaviors
-{
- public enum NavigationViewHeaderMode
- {
- Always,
- Never,
- Minimal
- }
-}
diff --git a/Sources/FluentMPC/Converters/BoolToBrushConverter.cs b/Sources/FluentMPC/Converters/BoolToBrushConverter.cs
deleted file mode 100644
index fdbb5749..00000000
--- a/Sources/FluentMPC/Converters/BoolToBrushConverter.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Windows.UI.Xaml;
-using Windows.UI.Xaml.Data;
-using Windows.UI.Xaml.Media;
-
-namespace FluentMPC.Helpers
-{
- ///
- /// Allows converting bools to solid color brushes
- ///
- public class BoolToBrushConverter : IValueConverter
- {
- public string TrueColor { get; set; }
-
- public string FalseColor { get; set; }
-
- public object Convert(object value, Type targetType, object parameter, string language)
- {
- var boolVal = value as bool?;
-
- if (!boolVal.HasValue)
- return Application.Current.Resources[FalseColor] as Brush;
-
- var returnVal = Application.Current.Resources[boolVal.Value ? TrueColor : FalseColor] as Brush;
-
- return returnVal;
- }
-
- public object ConvertBack(object value, Type targetType, object parameter, string language)
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/Sources/FluentMPC/Helpers/Observable.cs b/Sources/FluentMPC/Helpers/Observable.cs
deleted file mode 100644
index 203b9958..00000000
--- a/Sources/FluentMPC/Helpers/Observable.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System;
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
-
-namespace FluentMPC.Helpers
-{
- public class Observable : INotifyPropertyChanged
- {
- public event PropertyChangedEventHandler PropertyChanged;
-
- protected void Set(ref T storage, T value, [CallerMemberName]string propertyName = null)
- {
- if (Equals(storage, value))
- {
- return;
- }
-
- storage = value;
- OnPropertyChanged(propertyName);
- }
-
- protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
-}
diff --git a/Sources/FluentMPC/Helpers/RelayCommand.cs b/Sources/FluentMPC/Helpers/RelayCommand.cs
deleted file mode 100644
index e889ab22..00000000
--- a/Sources/FluentMPC/Helpers/RelayCommand.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using System;
-using System.Windows.Input;
-
-namespace FluentMPC.Helpers
-{
- public class RelayCommand : ICommand
- {
- private readonly Action _execute;
-
- private readonly Func _canExecute;
-
- public event EventHandler CanExecuteChanged;
-
- public RelayCommand(Action execute)
- : this(execute, null)
- {
- }
-
- public RelayCommand(Action execute, Func canExecute)
- {
- _execute = execute ?? throw new ArgumentNullException(nameof(execute));
- _canExecute = canExecute;
- }
-
- public bool CanExecute(object parameter) => _canExecute == null || _canExecute();
-
- public void Execute(object parameter) => _execute();
-
- public void OnCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
- }
-
- public class RelayCommand : ICommand
- {
- private readonly Action _execute;
-
- private readonly Func _canExecute;
-
- public event EventHandler CanExecuteChanged;
-
- public RelayCommand(Action execute)
- : this(execute, null)
- {
- }
-
- public RelayCommand(Action execute, Func canExecute)
- {
- _execute = execute ?? throw new ArgumentNullException(nameof(execute));
- _canExecute = canExecute;
- }
-
- public bool CanExecute(object parameter) => _canExecute == null || _canExecute((T)parameter);
-
- public void Execute(object parameter) => _execute((T)parameter);
-
- public void OnCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
- }
-}
diff --git a/Sources/FluentMPC/Helpers/ResourceExtensions.cs b/Sources/FluentMPC/Helpers/ResourceExtensions.cs
deleted file mode 100644
index 52d6297e..00000000
--- a/Sources/FluentMPC/Helpers/ResourceExtensions.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-
-using Windows.ApplicationModel.Resources;
-
-namespace FluentMPC.Helpers
-{
- internal static class ResourceExtensions
- {
- private static ResourceLoader _resLoader = new ResourceLoader();
-
- public static string GetLocalized(this string resourceKey)
- {
- return _resLoader.GetString(resourceKey);
- }
- }
-}
diff --git a/Sources/FluentMPC/Helpers/SettingsStorageExtensions.cs b/Sources/FluentMPC/Helpers/SettingsStorageExtensions.cs
deleted file mode 100644
index 9875ba43..00000000
--- a/Sources/FluentMPC/Helpers/SettingsStorageExtensions.cs
+++ /dev/null
@@ -1,140 +0,0 @@
-using Newtonsoft.Json;
-using System;
-using System.IO;
-using System.Threading.Tasks;
-
-using Windows.Storage;
-using Windows.Storage.Streams;
-
-namespace FluentMPC.Helpers
-{
-
- // Use these extension methods to store and retrieve local and roaming app data
- // More details regarding storing and retrieving app data at https://docs.microsoft.com/windows/uwp/app-settings/store-and-retrieve-app-data
- public static class SettingsStorageExtensions
- {
- private const string FileExtension = ".json";
-
- public static bool IsRoamingStorageAvailable(this ApplicationData appData)
- {
- return appData.RoamingStorageQuota == 0;
- }
-
- public static async Task SaveAsync(this StorageFolder folder, string name, T content)
- {
- var file = await folder.CreateFileAsync(GetFileName(name), CreationCollisionOption.ReplaceExisting);
- var fileContent = await Json.StringifyAsync(content);
-
- await FileIO.WriteTextAsync(file, fileContent);
- }
-
- public static async Task ReadAsync(this StorageFolder folder, string name)
- {
- if (!File.Exists(Path.Combine(folder.Path, GetFileName(name))))
- {
- return default(T);
- }
-
- var file = await folder.GetFileAsync($"{name}.json");
- var fileContent = await FileIO.ReadTextAsync(file);
-
- return await Json.ToObjectAsync(fileContent);
- }
-
- public static async Task SaveAsync(this ApplicationDataContainer settings, string key, T value)
- {
- settings.SaveString(key, await Json.StringifyAsync(value));
- }
-
- public static void SaveString(this ApplicationDataContainer settings, string key, string value)
- {
- settings.Values[key] = value;
- }
-
- public static async Task ReadAsync(this ApplicationDataContainer settings, string key)
- {
- object obj = null;
-
- if (settings.Values.TryGetValue(key, out obj))
- {
- return await Json.ToObjectAsync((string)obj);
- }
-
- return default(T);
- }
-
- public static async Task SaveFileAsync(this StorageFolder folder, byte[] content, string fileName, CreationCollisionOption options = CreationCollisionOption.ReplaceExisting)
- {
- if (content == null)
- {
- throw new ArgumentNullException(nameof(content));
- }
-
- if (string.IsNullOrEmpty(fileName))
- {
- throw new ArgumentException("ExceptionSettingsStorageExtensionsFileNameIsNullOrEmpty".GetLocalized(), nameof(fileName));
- }
-
- var storageFile = await folder.CreateFileAsync(fileName, options);
- await FileIO.WriteBytesAsync(storageFile, content);
- return storageFile;
- }
-
- public static async Task ReadFileAsync(this StorageFolder folder, string fileName)
- {
- var item = await folder.TryGetItemAsync(fileName).AsTask().ConfigureAwait(false);
-
- if ((item != null) && item.IsOfType(StorageItemTypes.File))
- {
- var storageFile = await folder.GetFileAsync(fileName);
- byte[] content = await storageFile.ReadBytesAsync();
- return content;
- }
-
- return null;
- }
-
- public static async Task ReadBytesAsync(this StorageFile file)
- {
- if (file != null)
- {
- using (IRandomAccessStream stream = await file.OpenReadAsync())
- {
- using (var reader = new DataReader(stream.GetInputStreamAt(0)))
- {
- await reader.LoadAsync((uint)stream.Size);
- var bytes = new byte[stream.Size];
- reader.ReadBytes(bytes);
- return bytes;
- }
- }
- }
-
- return null;
- }
-
- private static string GetFileName(string name)
- {
- return string.Concat(name, FileExtension);
- }
- }
-
- public static class Json
- {
- public static async Task ToObjectAsync(string value)
- {
- return await Task.Run(() =>
- {
- return JsonConvert.DeserializeObject(value);
- });
- }
-
- public static async Task StringifyAsync(object value)
- {
- return await Task.Run(() =>
- {
- return JsonConvert.SerializeObject(value);
- });
- }
- }
-}
diff --git a/Sources/FluentMPC/Helpers/Singleton.cs b/Sources/FluentMPC/Helpers/Singleton.cs
deleted file mode 100644
index 6fff65fa..00000000
--- a/Sources/FluentMPC/Helpers/Singleton.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-
-namespace FluentMPC.Helpers
-{
- public static class Singleton
- where T : new()
- {
- private static ConcurrentDictionary _instances = new ConcurrentDictionary();
-
- public static T Instance
- {
- get
- {
- return _instances.GetOrAdd(typeof(T), (t) => new T());
- }
- }
- }
-}
diff --git a/Sources/FluentMPC/Helpers/TaskExtensions.cs b/Sources/FluentMPC/Helpers/TaskExtensions.cs
deleted file mode 100644
index 2c6839d7..00000000
--- a/Sources/FluentMPC/Helpers/TaskExtensions.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-using System.Threading.Tasks;
-
-namespace FluentMPC.Helpers
-{
- public static class TaskExtensions
- {
- public static void FireAndForget(this Task task)
- {
- // This method allows you to call an async method without awaiting it.
- // Use it when you don't want or need to wait for the task to complete.
- }
- }
-}
diff --git a/Sources/FluentMPC/Services/BackgroundTaskService.cs b/Sources/FluentMPC/Services/BackgroundTaskService.cs
deleted file mode 100644
index e97c0634..00000000
--- a/Sources/FluentMPC/Services/BackgroundTaskService.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-
-using FluentMPC.Activation;
-using FluentMPC.BackgroundTasks;
-using FluentMPC.Helpers;
-using Windows.ApplicationModel.Activation;
-using Windows.ApplicationModel.Background;
-
-namespace FluentMPC.Services
-{
- internal class BackgroundTaskService : ActivationHandler
- {
- public static IEnumerable BackgroundTasks => BackgroundTaskInstances.Value;
-
- private static readonly Lazy> BackgroundTaskInstances =
- new Lazy>(() => CreateInstances());
-
- public async Task RegisterBackgroundTasksAsync()
- {
- BackgroundExecutionManager.RemoveAccess();
- var result = await BackgroundExecutionManager.RequestAccessAsync();
-
- if (result == BackgroundAccessStatus.DeniedBySystemPolicy
- || result == BackgroundAccessStatus.DeniedByUser)
- {
- return;
- }
-
- foreach (var task in BackgroundTasks)
- {
- task.Register();
- }
- }
-
- public static BackgroundTaskRegistration GetBackgroundTasksRegistration()
- where T : BackgroundTask
- {
- if (!BackgroundTaskRegistration.AllTasks.Any(t => t.Value.Name == typeof(T).Name))
- {
- // This condition should not be met. If it is it means the background task was not registered correctly.
- // Please check CreateInstances to see if the background task was properly added to the BackgroundTasks property.
- return null;
- }
-
- return (BackgroundTaskRegistration)BackgroundTaskRegistration.AllTasks.FirstOrDefault(t => t.Value.Name == typeof(T).Name).Value;
- }
-
- public void Start(IBackgroundTaskInstance taskInstance)
- {
- var task = BackgroundTasks.FirstOrDefault(b => b.Match(taskInstance?.Task?.Name));
-
- if (task == null)
- {
- // This condition should not be met. It is it it means the background task to start was not found in the background tasks managed by this service.
- // Please check CreateInstances to see if the background task was properly added to the BackgroundTasks property.
- return;
- }
-
- task.RunAsync(taskInstance).FireAndForget();
- }
-
- protected override async Task HandleInternalAsync(BackgroundActivatedEventArgs args)
- {
- Start(args.TaskInstance);
-
- await Task.CompletedTask;
- }
-
- private static IEnumerable CreateInstances()
- {
- var backgroundTasks = new List();
-
- backgroundTasks.Add(new LiveTileUpdateTask());
- return backgroundTasks;
- }
- }
-}
diff --git a/Sources/FluentMPC/Services/DialogService.cs b/Sources/FluentMPC/Services/DialogService.cs
deleted file mode 100644
index ee0835f9..00000000
--- a/Sources/FluentMPC/Services/DialogService.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-using System;
-using System.Threading.Tasks;
-
-using FluentMPC.Views;
-using Microsoft.Toolkit.Uwp;
-using Microsoft.Toolkit.Uwp.Helpers;
-
-using Windows.ApplicationModel.Core;
-using Windows.System;
-using Windows.UI.Core;
-using Windows.UI.Xaml.Controls;
-
-namespace FluentMPC.Services
-{
- public static class DialogService
- {
-
- ///
- ///
- ///
- /// If set to FALSE, the dialog will only allow you to create a new playlist.
- ///
- public static async Task ShowAddToPlaylistDialog(bool allowExistingPlaylists = true)
- {
- var dialog = new AddToPlaylistDialog(allowExistingPlaylists);
- var result = await DispatcherService.DispatcherQueue.EnqueueAsync(async () => await dialog.ShowAsync());
-
- // Return new playlist name if checked, selected playlist otherwise
- return result == ContentDialogResult.Primary ? dialog.AddNewPlaylist ? dialog.PlaylistName : dialog.SelectedPlaylist : null;
- }
-
- private static bool shown = false;
- internal static async Task ShowFirstRunDialogIfAppropriateAsync()
- {
- await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
- CoreDispatcherPriority.Normal, async () =>
- {
- if (SystemInformation.Instance.IsFirstRun && !shown)
- {
- shown = true;
- var dialog = new FirstRunDialog();
- await dialog.ShowAsync();
- }
- });
- }
- }
-}
diff --git a/Sources/FluentMPC/Services/LiveTileService.cs b/Sources/FluentMPC/Services/LiveTileService.cs
deleted file mode 100644
index ecd1147e..00000000
--- a/Sources/FluentMPC/Services/LiveTileService.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System;
-using System.Linq;
-using System.Threading.Tasks;
-
-using FluentMPC.Activation;
-using FluentMPC.Helpers;
-using Windows.ApplicationModel.Activation;
-using Windows.Storage;
-using Windows.UI.Notifications;
-
-namespace FluentMPC.Services
-{
- internal partial class LiveTileService : ActivationHandler
- {
- public void UpdateTile(TileNotification notification)
- {
- try
- {
- TileUpdateManager.CreateTileUpdaterForApplication().Clear();
- TileUpdateManager.CreateTileUpdaterForApplication().Update(notification);
- }
- catch (Exception)
- {
- // TODO WTS: Updating LiveTile can fail in rare conditions, please handle exceptions as appropriate to your scenario.
- }
- }
-
- protected override async Task HandleInternalAsync(LaunchActivatedEventArgs args)
- {
- await Task.CompletedTask;
- }
-
- protected override bool CanHandleInternal(LaunchActivatedEventArgs args)
- {
- return false;
- }
- }
-}
diff --git a/Sources/FluentMPC/Services/MPDConnectionService.cs b/Sources/FluentMPC/Services/MPDConnectionService.cs
deleted file mode 100644
index e5116dea..00000000
--- a/Sources/FluentMPC/Services/MPDConnectionService.cs
+++ /dev/null
@@ -1,297 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Threading;
-using System.Threading.Tasks;
-using CodeProject.ObjectPool;
-using FluentMPC.Helpers;
-using FluentMPC.ViewModels;
-using MpcNET;
-using MpcNET.Types;
-using MpcNET.Commands.Playlist;
-using MpcNET.Commands.Status;
-using MpcNET.Commands.Queue;
-using Sundew.Base.Collections;
-using Windows.System.Threading;
-using Windows.UI.Xaml;
-using Windows.UI.Core;
-using Windows.ApplicationModel.Core;
-
-namespace FluentMPC.Services
-{
- public class SongChangedEventArgs : EventArgs { public int NewSongId { get; set; } }
-
- public static class MPDConnectionService
- {
- private const int ConnectionPoolSize = 5;
- private static MpdStatus BOGUS_STATUS = new MpdStatus(0, false, false, false, false, -1, -1, -1, MpdState.Unknown, -1, -1, -1, -1, TimeSpan.Zero, TimeSpan.Zero, -1, -1, -1, -1, -1, "", "");
-
- public static MpdStatus CurrentStatus { get; private set; } = BOGUS_STATUS;
- public static string Version { get; private set; }
-
- public static bool DisableQueueEvents { get; set; }
-
- private static bool _connected;
-
- public static bool IsConnected
- {
- get { return _connected; }
-
- set
- {
- _connected = value;
- ConnectionChanged?.Invoke(Application.Current, new EventArgs());
-
- // If IsConnected = false, the RetryAttempter will call TryConnect() every five seconds.
- _connectionRetryAttempter?.Cancel();
- if (!value)
- {
- _connectionRetryAttempter = ThreadPoolTimer.CreatePeriodicTimer(async (source) => await TryConnecting(), TimeSpan.FromSeconds(5));
- }
- }
- }
-
- public static IList Playlists { get; private set; } = new List();
- public static ObjectPool> ConnectionPool;
-
- public static event EventHandler SongChanged;
- public static event EventHandler StatusChanged;
- public static event EventHandler QueueChanged;
- public static event EventHandler PlaylistsChanged;
- public static event EventHandler ConnectionChanged;
-
- private static MpcConnection _idleConnection;
- private static MpcConnection _statusConnection;
- private static IPEndPoint _mpdEndpoint;
-
- private static ThreadPoolTimer _statusUpdater;
- private static ThreadPoolTimer _connectionRetryAttempter;
- private static CancellationTokenSource _cancelIdle;
-
- public static async Task InitializeAsync()
- {
- _idleConnection?.SendAsync(new NoIdleCommand());
- _idleConnection?.DisconnectAsync();
- _statusConnection?.DisconnectAsync();
- _statusUpdater?.Cancel();
- _cancelIdle?.Cancel();
- _cancelIdle = new CancellationTokenSource();
-
- _idleConnection = null;
- _statusConnection = null;
- _connected = false;
-
- await TryConnecting();
- }
-
- public static async Task TryConnecting()
- {
- try
- {
- IPAddress.TryParse(Singleton.Instance.ServerHost, out var ipAddress);
- _mpdEndpoint = new IPEndPoint(ipAddress, Singleton.Instance.ServerPort);
- _idleConnection = await GetConnectionInternalAsync();
- _statusConnection = await GetConnectionInternalAsync();
-
- ConnectionPool = new ObjectPool>(ConnectionPoolSize,
- async (token) =>
- {
- var c = await GetConnectionInternalAsync(token);
- return new PooledObjectWrapper(c)
- {
- // Check our internal global IsConnected status
- OnValidateObject = (context) => IsConnected,
- OnReleaseResources = (c) => c?.DisconnectAsync()
- };
- }
- );
-
- // Connected, initialize basic data
- Version = _statusConnection.Version;
- await UpdatePlaylistsAsync();
- InitializeStatusUpdater(_cancelIdle.Token);
- IsConnected = true;
- }
- catch (Exception)
- {
- IsConnected = false;
- }
- }
-
- ///
- /// Get a raw MPD Connection. Please use instead when possible.
- ///
- ///
- ///
- public static async Task> GetConnectionAsync(CancellationToken token = default)
- {
- return await ConnectionPool.GetObjectAsync(token);
- }
-
- ///
- /// Send a command to the MPD server in an abstracted way. Shows notifications on screen if anything goes south.
- ///
- /// Return type of the command
- /// IMpcCommand to send
- /// The command results, or default value.
- public static async Task SafelySendCommandAsync(IMpcCommand command)
- {
- try
- {
- using (var c = await GetConnectionAsync())
- {
- var response = await c.InternalResource.SendAsync(command);
- if (!response.IsResponseValid)
- {
- // If we have an MpdError string, only show that as the error to avoid extra noise
- var mpdError = response.Response?.Result?.MpdError;
- if (mpdError != null)
- throw new Exception(mpdError);
- else
- throw new Exception($"Invalid server response: {response}.");
- }
-
- return response.Response.Content;
- }
- }
- catch (Exception e)
- {
- try
- {
- NotificationService.ShowInAppNotification($"Sending {command.GetType().Name} failed: {e.Message}", 0);
- } catch
- {
- // TODO: Dispatcher mismatch, we just swallow the exception for now.
- System.Diagnostics.Debugger.Break();
- }
- }
-
- return default(T);
- }
-
- private static async Task GetConnectionInternalAsync(CancellationToken token = default)
- {
- var c = new MpcConnection(_mpdEndpoint);
- await c.ConnectAsync(token);
- return c;
- }
-
- private static void InitializeStatusUpdater(CancellationToken token = default)
- {
- // Update status every second
- _statusUpdater = ThreadPoolTimer.CreatePeriodicTimer(async (source) => await UpdateStatusAsync(_statusConnection), TimeSpan.FromSeconds(1));
-
- // Run an idle loop in a spare thread to fire events when needed
- Task.Run(async () =>
- {
- while (true)
- {
- if (token.IsCancellationRequested || _idleConnection == null)
- break;
-
- var idleChanges = await _idleConnection.SendAsync(new IdleCommand("stored_playlist playlist player mixer output options"));
-
- if (idleChanges.IsResponseValid)
- await HandleIdleResponseAsync(idleChanges.Response.Content);
- else
- IsConnected = false;
- }
-
- });
- }
-
- private static async Task HandleIdleResponseAsync(string subsystems)
- {
- if (subsystems.Contains("playlist") && !DisableQueueEvents)
- {
- // Queue has changed
- QueueChanged?.Invoke(Application.Current, new EventArgs());
- }
-
- if (subsystems.Contains("stored_playlist"))
- {
- // m3u playlists have changed
- await UpdatePlaylistsAsync();
- }
-
- if (subsystems.Contains("player") || subsystems.Contains("mixer") || subsystems.Contains("output") || subsystems.Contains("options"))
- {
- // Status have changed in a significant way
- await UpdateStatusAsync(_idleConnection);
- StatusChanged?.Invoke(Application.Current, new EventArgs());
-
- if (subsystems.Contains("player"))
- {
- // Specifically, song has changed
- SongChanged?.Invoke(Application.Current, new SongChangedEventArgs { NewSongId = CurrentStatus.SongId });
- }
- }
- }
-
- private async static Task UpdateStatusAsync(MpcConnection connection)
- {
- System.Diagnostics.Debug.WriteLine($"{ConnectionPool.ObjectsInPoolCount} connections free in pool");
-
- if (_statusConnection == null) return;
-
- try
- {
- var response = await connection.SendAsync(new StatusCommand());
-
- if (response != null && response.IsResponseValid)
- {
- var oldstatus = CurrentStatus;
- CurrentStatus = response.Response.Content;
-
- if (oldstatus == BOGUS_STATUS) // Clean up the default null status if the idle command hasn't done it for us yet
- {
- StatusChanged?.Invoke(Application.Current, new EventArgs());
- SongChanged?.Invoke(Application.Current, new SongChangedEventArgs { NewSongId = CurrentStatus.SongId });
- }
- }
- else
- IsConnected = false;
- }
- catch
- {
- IsConnected = false;
- }
- }
-
- private async static Task UpdatePlaylistsAsync()
- {
- var response = await _idleConnection.SendAsync(new ListPlaylistsCommand());
-
- if (response.IsResponseValid)
- {
- var playlists = response.Response.Content;
-
- Playlists.Clear();
- Playlists.AddRange(playlists);
- PlaylistsChanged?.Invoke(Application.Current, new EventArgs());
- }
- else
- IsConnected = false;
- }
-
- ///
- /// Basic method to get the current song. Independent and meant to be called by background tasks.
- ///
- /// The current song as a MpdFile. Throws if anything else happens 🤷
- public static async Task GetCurrentSong()
- {
- IPAddress.TryParse(Singleton.Instance.ServerHost, out var ipAddress);
- _mpdEndpoint = new IPEndPoint(ipAddress, Singleton.Instance.ServerPort);
- var connection = await GetConnectionInternalAsync();
-
- var response = await connection.SendAsync(new CurrentSongCommand());
- await connection.DisconnectAsync();
-
- if (response.IsResponseValid)
- return response.Response.Content;
- else
- return null;
- }
- }
-}
diff --git a/Sources/FluentMPC/Services/NavigationService.cs b/Sources/FluentMPC/Services/NavigationService.cs
deleted file mode 100644
index 1ac4d5c9..00000000
--- a/Sources/FluentMPC/Services/NavigationService.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-using System;
-
-using Windows.UI.Xaml;
-using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Media.Animation;
-using Windows.UI.Xaml.Navigation;
-
-namespace FluentMPC.Services
-{
- public static class NavigationService
- {
- public static event NavigatedEventHandler Navigated;
-
- public static event NavigationFailedEventHandler NavigationFailed;
-
- private static Frame _frame;
- private static object _lastParamUsed;
-
- public static Frame Frame
- {
- get
- {
- if (_frame == null)
- {
- _frame = Window.Current.Content as Frame;
- RegisterFrameEvents();
- }
-
- return _frame;
- }
-
- set
- {
- UnregisterFrameEvents();
- _frame = value;
- RegisterFrameEvents();
- }
- }
-
- public static bool CanGoBack => Frame.CanGoBack;
-
- public static bool CanGoForward => Frame.CanGoForward;
-
- public static bool GoBack()
- {
- if (CanGoBack)
- {
- Frame.GoBack();
- return true;
- }
-
- return false;
- }
-
- public static void GoForward() => Frame.GoForward();
-
- public static bool Navigate(Type pageType, object parameter = null, NavigationTransitionInfo infoOverride = null)
- {
- // Don't open the same page multiple times
- if (Frame.Content?.GetType() != pageType || (parameter != null && !parameter.Equals(_lastParamUsed)))
- {
- var navigationResult = Frame.Navigate(pageType, parameter, infoOverride);
- if (navigationResult)
- {
- _lastParamUsed = parameter;
- }
-
- return navigationResult;
- }
- else
- {
- return false;
- }
- }
-
- public static bool Navigate(object parameter = null, NavigationTransitionInfo infoOverride = null)
- where T : Page
- => Navigate(typeof(T), parameter, infoOverride);
-
- private static void RegisterFrameEvents()
- {
- if (_frame != null)
- {
- _frame.Navigated += Frame_Navigated;
- _frame.NavigationFailed += Frame_NavigationFailed;
- }
- }
-
- private static void UnregisterFrameEvents()
- {
- if (_frame != null)
- {
- _frame.Navigated -= Frame_Navigated;
- _frame.NavigationFailed -= Frame_NavigationFailed;
- }
- }
-
- private static void Frame_NavigationFailed(object sender, NavigationFailedEventArgs e) => NavigationFailed?.Invoke(sender, e);
-
- private static void Frame_Navigated(object sender, NavigationEventArgs e) => Navigated?.Invoke(sender, e);
- }
-}
diff --git a/Sources/FluentMPC/Services/ThemeSelectorService.cs b/Sources/FluentMPC/Services/ThemeSelectorService.cs
deleted file mode 100644
index 0bb38451..00000000
--- a/Sources/FluentMPC/Services/ThemeSelectorService.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-using System;
-using System.Threading.Tasks;
-
-using FluentMPC.Helpers;
-
-using Windows.ApplicationModel.Core;
-using Windows.Storage;
-using Windows.UI;
-using Windows.UI.Core;
-using Windows.UI.ViewManagement;
-using Windows.UI.Xaml;
-
-namespace FluentMPC.Services
-{
- public static class ThemeSelectorService
- {
- private const string SettingsKey = "AppBackgroundRequestedTheme";
-
- public static ElementTheme Theme { get; set; } = ElementTheme.Default;
-
- public static async Task InitializeAsync()
- {
- Theme = await LoadThemeFromSettingsAsync();
- }
-
- public static async Task SetThemeAsync(ElementTheme theme)
- {
- Theme = theme;
-
- await SetRequestedThemeAsync();
- await SaveThemeInSettingsAsync(Theme);
- }
-
- public static async Task SetRequestedThemeAsync()
- {
- foreach (var view in CoreApplication.Views)
- {
- await view.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
- {
- if (Window.Current.Content is FrameworkElement frameworkElement)
- {
- frameworkElement.RequestedTheme = Theme;
-
- // https://stackoverflow.com/questions/48201278/uwp-changing-titlebar-buttonforegroundcolor-with-themeresource
- Color color;
- var appTheme = Application.Current.RequestedTheme;
-
- switch (Theme)
- {
- case ElementTheme.Default:
- color = ((Color)Application.Current.Resources["SystemBaseHighColor"]);
- break;
- case ElementTheme.Light:
- if (appTheme == ApplicationTheme.Light) { color = ((Color)Application.Current.Resources["SystemBaseHighColor"]); }
- else { color = ((Color)Application.Current.Resources["SystemAltHighColor"]); }
- break;
- case ElementTheme.Dark:
- if (appTheme == ApplicationTheme.Light) { color = ((Color)Application.Current.Resources["SystemAltHighColor"]); }
- else { color = ((Color)Application.Current.Resources["SystemBaseHighColor"]); }
- break;
- default:
- break;
- }
-
- ApplicationViewTitleBar titleBar = ApplicationView.GetForCurrentView().TitleBar;
- titleBar.ButtonForegroundColor = color;
- }
- });
- }
- }
-
- private static async Task LoadThemeFromSettingsAsync()
- {
- ElementTheme cacheTheme = ElementTheme.Default;
- string themeName = await ApplicationData.Current.LocalSettings.ReadAsync(SettingsKey);
-
- if (!string.IsNullOrEmpty(themeName))
- {
- Enum.TryParse(themeName, out cacheTheme);
- }
-
- return cacheTheme;
- }
-
- private static async Task SaveThemeInSettingsAsync(ElementTheme theme)
- {
- await ApplicationData.Current.LocalSettings.SaveAsync(SettingsKey, theme.ToString());
- }
- }
-}
diff --git a/Sources/FluentMPC/Styles/Page.xaml b/Sources/FluentMPC/Styles/Page.xaml
deleted file mode 100644
index 87831a8a..00000000
--- a/Sources/FluentMPC/Styles/Page.xaml
+++ /dev/null
@@ -1,315 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Sources/FluentMPC/Styles/TextBlock.xaml b/Sources/FluentMPC/Styles/TextBlock.xaml
deleted file mode 100644
index 54ffd6eb..00000000
--- a/Sources/FluentMPC/Styles/TextBlock.xaml
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Sources/FluentMPC/Styles/_Colors.xaml b/Sources/FluentMPC/Styles/_Colors.xaml
deleted file mode 100644
index 40d61b94..00000000
--- a/Sources/FluentMPC/Styles/_Colors.xaml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Sources/FluentMPC/Styles/_FontSizes.xaml b/Sources/FluentMPC/Styles/_FontSizes.xaml
deleted file mode 100644
index a19f4a3c..00000000
--- a/Sources/FluentMPC/Styles/_FontSizes.xaml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- 24
- 16
-
-
-
-
-
diff --git a/Sources/FluentMPC/ViewModels/FoldersViewModel.cs b/Sources/FluentMPC/ViewModels/FoldersViewModel.cs
deleted file mode 100644
index 47ef960d..00000000
--- a/Sources/FluentMPC/ViewModels/FoldersViewModel.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using System;
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Threading.Tasks;
-using System.Windows.Input;
-
-using FluentMPC.Helpers;
-using FluentMPC.Services;
-using FluentMPC.ViewModels.Items;
-using MpcNET.Commands.Database;
-using MpcNET.Types;
-using WinUI = Microsoft.UI.Xaml.Controls;
-
-namespace FluentMPC.ViewModels
-{
- public class FoldersViewModel : Observable
- {
- public ObservableCollection SourceData { get; } = new ObservableCollection();
- public bool IsSourceEmpty => SourceData.Count == 0;
-
- public FoldersViewModel()
- {
- SourceData.CollectionChanged += (s, e) => OnPropertyChanged(nameof(IsSourceEmpty));
- }
-
- public async Task LoadDataAsync()
- {
- SourceData.Clear();
-
- var response = await MPDConnectionService.SafelySendCommandAsync(new LsInfoCommand("/"));
-
- if (response != null)
- foreach (var item in response)
- {
- SourceData.Add(new FilePathViewModel(item));
- }
-
- OnPropertyChanged(nameof(SourceData));
- }
-
- }
-}
diff --git a/Sources/FluentMPC/ViewModels/Items/AlbumViewModel.cs b/Sources/FluentMPC/ViewModels/Items/AlbumViewModel.cs
deleted file mode 100644
index 85674a7f..00000000
--- a/Sources/FluentMPC/ViewModels/Items/AlbumViewModel.cs
+++ /dev/null
@@ -1,234 +0,0 @@
-using FluentMPC.Helpers;
-using FluentMPC.Services;
-using Microsoft.Toolkit.Uwp.Helpers;
-using MpcNET;
-using MpcNET.Commands.Database;
-using MpcNET.Commands.Playback;
-using MpcNET.Commands.Playlist;
-using MpcNET.Commands.Queue;
-using MpcNET.Commands.Reflection;
-using MpcNET.Tags;
-using MpcNET.Types;
-using Sundew.Base.Collections;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Windows.Input;
-using Windows.System.Threading;
-using Windows.UI;
-using Windows.UI.Xaml;
-using Windows.UI.Xaml.Media.Imaging;
-
-namespace FluentMPC.ViewModels.Items
-{
- public class AlbumViewModel : Observable
- {
- public string Name
- {
- get => _name;
- set => Set(ref _name, value);
- }
- private string _name;
-
- public string Artist
- {
- get => _artist;
- private set
- {
- DispatcherService.ExecuteOnUIThreadAsync(() => Set(ref _artist, value));
- }
- }
- private string _artist;
-
- public IList Files
- {
- get => _files;
- set => Set(ref _files, value);
- }
- private IList _files;
-
- private bool _detailLoading;
- public bool IsDetailLoading
- {
- get => _detailLoading;
- internal set
- {
- DispatcherService.ExecuteOnUIThreadAsync(() => Set(ref _detailLoading, value));
- }
- }
-
- private bool _artLoaded;
- public bool AlbumArtLoaded
- {
- get => _artLoaded;
- private set
- {
- DispatcherService.ExecuteOnUIThreadAsync(() => Set(ref _artLoaded, value));
- }
- }
-
- public BitmapImage AlbumArt
- {
- get => _albumArt;
- private set
- {
- DispatcherService.ExecuteOnUIThreadAsync(() => Set(ref _albumArt, value));
- }
- }
-
- internal void SetAlbumArt(AlbumArt art)
- {
- if (art != null)
- {
- AlbumArt = art.ArtBitmap;
- IsLight = !art.DominantColor.IsDark;
- DominantColor = art.DominantColor.ToWindowsColor();
- }
-
- AlbumArtLoaded = true;
- }
-
- private BitmapImage _albumArt;
-
- public Color DominantColor
- {
- get => _albumColor;
- private set
- {
- DispatcherService.ExecuteOnUIThreadAsync(() => Set(ref _albumColor, value));
- }
- }
-
- private Color _albumColor;
-
- private bool _isLight;
- ///
- /// If the dominant color of the album is too light to show white text on top of, this boolean will be true.
- ///
- public bool IsLight
- {
- get => _isLight;
- private set
- {
- DispatcherService.ExecuteOnUIThreadAsync(() => Set(ref _isLight, value));
- }
- }
-
- private ICommand _addToPlaylistCommand;
- public ICommand AddToPlaylistCommand => _addToPlaylistCommand ?? (_addToPlaylistCommand = new RelayCommand(AddToPlaylist));
- private async void AddToPlaylist()
- {
- var playlistName = await DialogService.ShowAddToPlaylistDialog();
- if (playlistName == null || Files.Count == 0) return;
-
- var commandList = new CommandList();
-
- foreach (var f in Files)
- {
- commandList.Add(new PlaylistAddCommand(playlistName, f.Path));
- }
-
- if (await MPDConnectionService.SafelySendCommandAsync(commandList) != null)
- {
- NotificationService.ShowInAppNotification(string.Format("AddedToPlaylistText".GetLocalized(), playlistName));
- }
- }
-
- private ICommand _addToQueueCommand;
- public ICommand AddAlbumCommand => _addToQueueCommand ?? (_addToQueueCommand = new RelayCommand(AddToQueue));
- private async void AddToQueue()
- {
- var commandList = new CommandList();
-
- if (Files.Count == 0)
- {
- NotificationService.ShowInAppNotification(string.Format("ErrorAddingAlbum".GetLocalized(), "NoTracksLoaded".GetLocalized()), 0);
- return;
- }
-
- foreach (var f in Files)
- {
- commandList.Add(new AddCommand(f.Path));
- }
-
- if (await MPDConnectionService.SafelySendCommandAsync(commandList) != null)
- NotificationService.ShowInAppNotification("AddedToQueueText".GetLocalized());
- }
-
- private ICommand _playCommand;
- public ICommand PlayAlbumCommand => _playCommand ?? (_playCommand = new RelayCommand(PlayAlbum));
- private async void PlayAlbum()
- {
- if (Files.Count == 0)
- {
- NotificationService.ShowInAppNotification(string.Format("ErrorPlayingText".GetLocalized(), "NoTracksLoaded".GetLocalized()), 0);
- return;
- }
-
- var commandList = new CommandList();
-
- // Clear queue, add album and play
- commandList.Add(new ClearCommand());
-
- foreach (var f in Files)
- {
- commandList.Add(new AddCommand(f.Path));
- }
-
- commandList.Add(new PlayCommand(0));
-
- if (await MPDConnectionService.SafelySendCommandAsync(commandList) != null)
- {
- // Auto-navigate to the queue
- NavigationService.Navigate(typeof(Views.ServerQueuePage));
- NotificationService.ShowInAppNotification(string.Format("NowPlayingText".GetLocalized(), Name));
- }
- }
-
- public AlbumViewModel(string albumName)
- {
- Name = albumName;
- DominantColor = (Color)Application.Current.Resources["SystemAccentColor"];
- Files = new List();
- IsDetailLoading = false;
-
- AlbumArt = new BitmapImage(new Uri("ms-appx:///Assets/AlbumPlaceholder.png"));
- }
-
- public async Task LoadAlbumDataAsync(MpcConnection c)
- {
- IsDetailLoading = true;
- try
- {
- var findReq = await c.SendAsync(new FindCommand(MpdTags.Album, Name));
- if (!findReq.IsResponseValid)
- return;
-
- // If files were already added, don't re-add them.
- // This can occasionally happen if the server is a bit overloaded when we look at an album, since AlbumDetailViewModel can call this method a second time.
- if (Files.Count == 0)
- Files.AddRange(findReq.Response.Content);
-
- Artist = Files.Select(f => f.Artist).Distinct().Aggregate((f1, f2) => $"{f1}, {f2}");
-
- // If we've already generated album art, don't use the queue and directly grab it
- if (await AlbumArtService.IsAlbumArtCachedAsync(Files[0]))
- {
- var art = await AlbumArtService.GetAlbumArtAsync(Files[0], true, 180);
- SetAlbumArt(art);
- }
- else
- {
- // Queue this VM in the AlbumArtService so its album art is eventually recovered from the server
- AlbumArtService.QueueAlbumArt(this);
- }
- }
- finally
- {
- IsDetailLoading = false;
- }
- }
- }
-}
diff --git a/Sources/FluentMPC/ViewModels/Items/FilePathViewModel.cs b/Sources/FluentMPC/ViewModels/Items/FilePathViewModel.cs
deleted file mode 100644
index 9eb58de5..00000000
--- a/Sources/FluentMPC/ViewModels/Items/FilePathViewModel.cs
+++ /dev/null
@@ -1,144 +0,0 @@
-using FluentMPC.Helpers;
-using FluentMPC.Services;
-using MpcNET.Commands.Database;
-using MpcNET.Commands.Playback;
-using MpcNET.Commands.Playlist;
-using MpcNET.Types;
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using System.Windows.Input;
-using System.Collections.ObjectModel;
-using Sundew.Base.Collections;
-using System.Linq;
-using MpcNET.Commands.Queue;
-using MpcNET.Commands.Reflection;
-using MpcNET;
-
-namespace FluentMPC.ViewModels.Items
-{
- public class FilePathViewModel : Observable
- {
- private string _path;
-
- public string Path
- {
- get => _path;
- private set => Set(ref _path, value);
- }
-
- private string _name;
-
- public string Name
- {
- get => _name;
- private set => Set(ref _name, value);
- }
-
- public bool IsDirectory { get; set; }
- public bool IsLoaded { get; set; }
-
- private ObservableCollection _childPaths;
- public ObservableCollection Children
- {
- get => _childPaths;
- set => Set(ref _childPaths, value);
- }
-
- private bool _isLoadingChildren;
- public async Task LoadChildrenAsync()
- {
- if (IsLoaded || _isLoadingChildren || IsDirectory == false || _childPaths == null || Path == null) return;
-
- _isLoadingChildren = true;
- try
- {
- var newChildren = new List();
-
- var response = await MPDConnectionService.SafelySendCommandAsync(new LsInfoCommand(Path));
-
- if (response != null)
- foreach (var item in response)
- {
- newChildren.Add(new FilePathViewModel(item));
- }
- else
- newChildren.Add(new FilePathViewModel("💥 Failed"));
-
- await DispatcherService.ExecuteOnUIThreadAsync(() =>
- {
- _childPaths.AddRange(newChildren);
- _childPaths.RemoveAt(0); // Remove the placeholder after adding the new items, otherwise the treeitem can close back up
- IsLoaded = true;
- });
- }
- finally
- {
- _isLoadingChildren = false;
- }
- }
-
- private ICommand _playCommand;
- public ICommand PlayCommand => _playCommand ?? (_playCommand = new RelayCommand(PlayPath));
-
- private async void PlayPath()
- {
- // Clear queue, add path and play
- var commandList = new CommandList(new IMpcCommand